Skip to content

Commit

Permalink
Various improve (#72)
Browse files Browse the repository at this point in the history
* モジュールの順番を入れ替え可能にした

* ・モジュール一覧のソート順を初期化する機能を追加
・モジュール一覧のコンテキストメニュー関連処理を別クラスに切り分けた
・モジュール一覧がソートされている場合、手動で並べ替え出来ないようにした

* モジュール一覧のソート順をクリアしても列ヘッダに三角マークが残らないように修正

* 一部のBindingExpressionを解消

* 設定→ステーション→本部がチェック入の場合にモジュール一覧を全削除すると、
概要→労働力の必要労働者数が不正になり、
概要→労働力→モジュール情報から不明なモジュール(本部)が消えるのを修正

* モジュール一覧がソート済みの場合でも並べ替え可能にした

* ソート順クリア可能なDataGridのコンストラクタをstaticに変更

* 帝国の概要画面でまれにInvalidOperationExceptionが発生するのを対策
  • Loading branch information
Ocelot1210 authored Oct 7, 2020
1 parent cf33a32 commit 6964547
Show file tree
Hide file tree
Showing 16 changed files with 762 additions and 190 deletions.
13 changes: 13 additions & 0 deletions X4_ComplexCalculator/Common/IReorderble.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace X4_ComplexCalculator.Common
{
/// <summary>
/// 順番を入れ替え可能なコレクションの要素に対するインターフェイス
/// </summary>
interface IReorderble
{
/// <summary>
/// 順番入れ替え対象か
/// </summary>
public bool IsReorderTarget { get; set; }
}
}
14 changes: 6 additions & 8 deletions X4_ComplexCalculator/Localization/Lang.csv
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ Remarks;Remarks
PresetImported;Imported.


# ------------------------------------------------------
# Empire overview
# ------------------------------------------------------



# ------------------------------------------------------
# Plan
# ------------------------------------------------------
Expand All @@ -149,8 +143,6 @@ Summary;Summary
BuildResources;Build resources
Storages;Storages
StorageAssign;Storage assign
Buy;Buy
Sell;Sell


# ------------------------------------------------------
Expand All @@ -159,6 +151,10 @@ Sell;Sell
Copy;Copy
Paste;Paste
Delete;Delete
ClearSelection;Clear selection
MoveUpTheSelection;Move up the selection
MoveDownTheSelection;Move down the selection
ResetSortOrder;Reset sort order
Add;Add
AutoAdd;Auto add
Merge;Merge
Expand All @@ -185,6 +181,8 @@ ProductName;Product name
AmountPerHour;Amount/h
NoBuy;No buy
NoSell;No sell
Buy;Buy
Sell;Sell


# ------------------------------------------------------
Expand Down
8 changes: 6 additions & 2 deletions X4_ComplexCalculator/Localization/Lang.en-US.csv
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@ Summary;Summary
BuildResources;Build resources
Storages;Storages
StorageAssign;Storage assign
Buy;Buy
Sell;Sell


# ------------------------------------------------------
Expand All @@ -153,6 +151,10 @@ Sell;Sell
Copy;Copy
Paste;Paste
Delete;Delete
ClearSelection;Clear selection
MoveUpTheSelection;Move up the selection
MoveDownTheSelection;Move down the selection
ResetSortOrder;Reset sort order
Add;Add
AutoAdd;Auto add
Merge;Merge
Expand All @@ -179,6 +181,8 @@ ProductName;Product name
AmountPerHour;Amount/h
NoBuy;No buy
NoSell;No sell
Buy;Buy
Sell;Sell


# ------------------------------------------------------
Expand Down
4 changes: 4 additions & 0 deletions X4_ComplexCalculator/Localization/Lang.ja-JP.csv
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ StorageAssign;保管庫割当
Copy;コピー
Paste;ペースト
Delete;削除
ClearSelection;選択解除
MoveUpTheSelection;選択項目を上に移動
MoveDownTheSelection;選択項目を下に移動
ResetSortOrder;ソート順を初期化
Add;追加
AutoAdd;自動追加
Merge;マージ
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,11 @@ private void Products_CollectionPropertyChanged(object sender, PropertyChangedEv
return;
}

Products.First(x => x.Ware.WareID == product.Ware.WareID).Count += ev.NewValue - ev.OldValue;
var prod = Products.FirstOrDefault(x => x.Ware.WareID == product.Ware.WareID);
if (prod != null)
{
prod.Count += ev.NewValue - ev.OldValue;
}
}
break;

Expand Down Expand Up @@ -203,7 +207,12 @@ private void OnProductsRemoved(IList<ProductsGridItem> parent, IEnumerable<Produ
// 削除された製品の生産/消費量を減算する
foreach (var removedItem in removedItems)
{
Products.First(x => x.Ware.WareID == removedItem.Ware.WareID).Count -= removedItem.Count;
var prod = Products.FirstOrDefault(x => x.Ware.WareID == removedItem.Ware.WareID);
if (prod != null)
{
prod.Count -= removedItem.Count;
}

prodBak.Remove(removedItem);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Xml.Linq;
using X4_ComplexCalculator.Common.EditStatus;
using X4_ComplexCalculator.Main.WorkArea.WorkAreaData.Modules;

namespace X4_ComplexCalculator.Main.WorkArea.UI.ModulesGrid
{
/// <summary>
/// モジュール一覧タブのコンテキストメニューの処理用クラス
/// </summary>
public class ContextMenuOperation : BindableBase, IDisposable
{
#region メンバ
/// <summary>
/// モジュール一覧
/// </summary>
private readonly IModulesInfo _ModulesInfo;


/// <summary>
/// モジュール一覧(表示用)
/// </summary>
private readonly ListCollectionView _CollectionView;


/// <summary>
/// モジュール並び替え用
/// </summary>
private readonly ModulesReorder _ModuleReorder;
#endregion


#region プロパティ
/// <summary>
/// モジュールをコピー
/// </summary>
public ICommand CopyModulesCommand { get; }


/// <summary>
/// モジュールを貼り付け
/// </summary>
public ICommand PasteModulesCommand { get; }


/// <summary>
/// モジュールを削除
/// </summary>
public ICommand DeleteModulesCommand { get; }

// ---------------------------------------------------------------------- //

/// <summary>
/// モジュール選択
/// </summary>
public ICommand SelectModulesCommand => _ModuleReorder.SelectModulesCommand;


/// <summary>
/// モジュール選択解除
/// </summary>
public ICommand ClearSelectionCommand => _ModuleReorder.ClearSelectionCommand;


/// <summary>
/// 選択項目を上に移動する
/// </summary>
public ICommand MoveUpTheSelectionCommand => _ModuleReorder.MoveUpTheSelectionCommand;


/// <summary>
/// 選択項目を下に移動する
/// </summary>
public ICommand MoveDownTheSelectionCommand => _ModuleReorder.MoveDownTheSelectionCommand;


// ---------------------------------------------------------------------- //

/// <summary>
/// ソート順を初期化
/// </summary>
public DelegateCommand ResetSortOrderCommand { get; }

// ---------------------------------------------------------------------- //

/// <summary>
/// セルフォーカス用のコマンド
/// </summary>
public ICommand? CellFocusCommand { private get; set; }
#endregion


/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="modulesInfo">モジュール一覧情報</param>
/// <param name="listCollectionView">モジュール一覧のCollectionView</param>
public ContextMenuOperation(IModulesInfo modulesInfo, ListCollectionView listCollectionView)
{
_ModulesInfo = modulesInfo;
_CollectionView = listCollectionView;
_ModuleReorder = new ModulesReorder(modulesInfo, listCollectionView);

((INotifyCollectionChanged)_CollectionView.SortDescriptions).CollectionChanged += ContextMenuOperation_CollectionChanged;

CopyModulesCommand = new DelegateCommand(CopyModules);
PasteModulesCommand = new DelegateCommand<DataGrid>(PasteModules);
DeleteModulesCommand = new DelegateCommand<DataGrid>(DeleteModules);
ResetSortOrderCommand = new DelegateCommand(
() => _CollectionView.SortDescriptions.Clear(),
() => 0 < _CollectionView.SortDescriptions.Count
);
}


/// <inheritdoc/>
public void Dispose()
{
((INotifyCollectionChanged)_CollectionView.SortDescriptions).CollectionChanged -= ContextMenuOperation_CollectionChanged;
}


/// <summary>
/// ソート内容が変更された場合
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ContextMenuOperation_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// 未ソートの場合のみ入れ替え可能にする
_ModuleReorder.SortedColumnCount = _CollectionView.SortDescriptions.Count;

// ソート順初期化可不可更新
ResetSortOrderCommand.RaiseCanExecuteChanged();
}


/// <summary>
/// 選択中のモジュールをコピー
/// </summary>
private void CopyModules()
{
var xml = new XElement("modules");
var selectedModules = CollectionViewSource.GetDefaultView(_CollectionView)
.Cast<ModulesGridItem>()
.Where(x => x.IsSelected);

foreach (var module in selectedModules)
{
xml.Add(module.ToXml());
}

Clipboard.SetText(xml.ToString());
}


/// <summary>
/// コピーしたモジュールを貼り付け
/// </summary>
/// <param name="dataGrid"></param>
private void PasteModules(DataGrid dataGrid)
{
try
{
var clipboardXml = XDocument.Parse(Clipboard.GetText());

// xmlの内容に問題がないか確認するため、ここでToArray()する
var modules = clipboardXml.Root.Elements().Select(x => new ModulesGridItem(x) { EditStatus = EditStatus.Edited }).ToArray();

_ModulesInfo.Modules.AddRange(modules);

dataGrid.Focus();
}
catch
{

}
}


/// <summary>
/// 選択中のモジュールを削除
/// </summary>
/// <param name="dataGrid"></param>
private void DeleteModules(DataGrid dataGrid)
{
var currPos = _CollectionView.CurrentPosition;

// モジュール数を編集した後に削除するとcurrPosが-1になる場合があるため、
// ここで最初に選択されている表示上のモジュールの要素番号を取得する
if (currPos == -1)
{
var cnt = 0;
foreach (var module in _CollectionView.OfType<ModulesGridItem>())
{
if (module.IsSelected)
{
currPos = cnt;
break;
}
cnt++;
}
}

var items = CollectionViewSource.GetDefaultView(_CollectionView)
.Cast<ModulesGridItem>()
.Where(x => x.IsSelected);

_ModulesInfo.Modules.RemoveRange(items);

// 削除後に全部の選択状態を外さないと余計なものまで選択される
foreach (var module in _ModulesInfo.Modules)
{
module.IsSelected = false;
}

// 選択行を設定
if (currPos < 0)
{
// 先頭行を削除した場合
_CollectionView.MoveCurrentToFirst();
}
else if (_CollectionView.Count <= currPos)
{
// 最後の行を消した場合、選択行を最後にする
_CollectionView.MoveCurrentToLast();
}
else
{
// 中間行の場合
_CollectionView.MoveCurrentToPosition(currPos);
}

// 再度選択
if (_CollectionView.CurrentItem is ModulesGridItem item)
{
item.IsSelected = true;
}

// セルフォーカス
if (dataGrid.CurrentCell.Column != null)
{
CellFocusCommand?.Execute(new Tuple<DataGrid, int, int>(dataGrid, _CollectionView.CurrentPosition, dataGrid.CurrentCell.Column.DisplayIndex));
}
}
}
}
Loading

0 comments on commit 6964547

Please sign in to comment.