diff --git a/Core/Abstracts/AbstractFilter.cs b/Core/Abstracts/AbstractFilter.cs index 17ac2f1..96d41d5 100644 --- a/Core/Abstracts/AbstractFilter.cs +++ b/Core/Abstracts/AbstractFilter.cs @@ -11,8 +11,10 @@ using Core.Abstracts; using Core.Filter; using Core.Data; -using static Core.Filter.FilterManager; using System.Runtime.Remoting.Contexts; +using System.Windows.Input; +using System.Windows.Data; +using System.Drawing.Printing; @@ -42,7 +44,7 @@ public class Configuration : IAbstractConfigurationData public class ContentMetadata { - public string Name { get; set; } + public Binding NameBinding { get; set; } public int DataUID { get; set; } } @@ -65,20 +67,23 @@ public enum ListModification #region public properties public int _UID { get; } = UniqueID.GenerateInt(); - public string _Name { get; set; } + public string _Name { get { return _filter_caption.Text; } protected set { _filter_caption.Text = value; } } #endregion /* ------------------------------------------------------------------*/ #region public functions - public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_data_callback, DataManager.UpdateSelectedDataCallback_Delegate update_selected_data_callback, ModifyUIFilterList_Delegate modify_ui_filter_list_callback) + public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_data_callback, + DataManager.UpdateSelectedDataCallback_Delegate update_selected_data_callback, + FilterManager.ModifyUIFilterList_Delegate modify_ui_filter_list_callback, + FilterManager.DeleteFilterCallback_Delegate delete_self_callback) { if (_initialized) { Terminate(); } - if ((get_selected_data_callback == null) || (update_selected_data_callback == null) || (modify_ui_filter_list_callback == null)) + if ((get_selected_data_callback == null) || (update_selected_data_callback == null) || (modify_ui_filter_list_callback == null) || (delete_self_callback == null)) { Log.Default.Msg(Log.Level.Error, "Missing callback(s)"); } @@ -88,7 +93,7 @@ public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_ _update_selected_data_callback = update_selected_data_callback; _get_selected_data_callback = get_selected_data_callback; _modify_ui_filter_list_callback = modify_ui_filter_list_callback; - + _delete_self_callback = delete_self_callback; _timer.Stop(); _initialized = true; @@ -106,6 +111,10 @@ public override bool Terminate() _modify_ui_filter_list_callback(_content, ListModification.DELETE); _content = null; + _filter_caption = null; + _visualizations_list = null; + _apply_button = null; + _update_selected_data_callback = null; _get_selected_data_callback = null; _modify_ui_filter_list_callback = null; @@ -133,24 +142,150 @@ public virtual bool CreateUI() } _timer.Start(); + _content = new Border(); + _filter_caption = new RenameLabel(); + _visualizations_list = new StackPanel(); + _apply_button = new Button(); - _content = new Grid(); + _filter_caption.Margin = new Thickness(_margin, _margin, _margin, 0.0); + _filter_caption.HorizontalAlignment = HorizontalAlignment.Stretch; - var rename_button = new Button(); - var endisable_button = new Button(); - var delete_button = new Button(); - var apply_button = new Button(); // Disable on hit, but enable when anything changes + var button_grid = new Grid(); + + _apply_button.Content = " Apply "; + _apply_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + _apply_button.Click += _apply_button_click; + set_filter_dirty(); - // Subscribe to list update (add/delete content with own data) List Visualization Name -> binding/ Data UID + var button_column = new ColumnDefinition(); + button_column.Width = new GridLength(0.0, GridUnitType.Auto); + button_grid.ColumnDefinitions.Add(button_column); + Grid.SetColumn(_apply_button, 0); + button_grid.Children.Add(_apply_button); + + var rename_button = new Button(); + rename_button.Content = " Rename "; + rename_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + rename_button.Click += (object sender, RoutedEventArgs e) => + { + _filter_caption.Focusable = true; + _filter_caption.Style = null; + _filter_caption.Cursor = null; + _filter_caption.Focus(); + }; + button_column = new ColumnDefinition(); + button_column.Width = new GridLength(0.0, GridUnitType.Auto); + button_grid.ColumnDefinitions.Add(button_column); + Grid.SetColumn(rename_button, 1); + button_grid.Children.Add(rename_button); + + var disable_button = new Button(); + disable_button.Content = " Disable "; + disable_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + disable_button.IsEnabled = false; + button_column = new ColumnDefinition(); + button_column.Width = new GridLength(0.0, GridUnitType.Auto); + button_grid.ColumnDefinitions.Add(button_column); + Grid.SetColumn(disable_button, 2); + button_grid.Children.Add(disable_button); + + var delete_button = new Button(); + delete_button.Content = " Delete "; + delete_button.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + delete_button.Click += (object sender, RoutedEventArgs e) => + { + if (_delete_self_callback != null) + { + _delete_self_callback(_UID); + } + else + { + Log.Default.Msg(Log.Level.Error, "Missing callback."); + } + }; + button_column = new ColumnDefinition(); + button_column.Width = new GridLength(0.0, GridUnitType.Auto); + button_grid.ColumnDefinitions.Add(button_column); + Grid.SetColumn(delete_button, 3); + button_grid.Children.Add(delete_button); + + var apply_grid = new Grid(); + + var list_label = new TextBlock(); + list_label.Text = "Select Content"; + list_label.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + var apply_text_column = new ColumnDefinition(); + apply_text_column.Width = new GridLength(1.0, GridUnitType.Auto); + apply_grid.ColumnDefinitions.Add(apply_text_column); + Grid.SetColumn(_apply_button, 0); + apply_grid.Children.Add(list_label); + + var hrule = new Border(); + hrule.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); + hrule.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); + hrule.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); + hrule.Margin = new Thickness(_margin, _margin, _margin, _margin); + hrule.CornerRadius = new CornerRadius(0); + hrule.Height = 2.0; + hrule.VerticalAlignment = VerticalAlignment.Bottom; + hrule.HorizontalAlignment = HorizontalAlignment.Stretch; + var apply_rule_column = new ColumnDefinition(); + apply_rule_column.Width = new GridLength(1.0, GridUnitType.Star); + apply_grid.ColumnDefinitions.Add(apply_rule_column); + Grid.SetColumn(hrule, 1); + apply_grid.Children.Add(hrule); + + var content_grid = new Grid(); + + var caption_row = new RowDefinition(); + caption_row.Height = new GridLength(1.0, GridUnitType.Auto); + content_grid.RowDefinitions.Add(caption_row); + Grid.SetRow(_filter_caption, 0); + content_grid.Children.Add(_filter_caption); + + var button_row = new RowDefinition(); + button_row.Height = new GridLength(1.0, GridUnitType.Auto); + content_grid.RowDefinitions.Add(button_row); + Grid.SetRow(button_grid, 1); + content_grid.Children.Add(button_grid); + + var list_caption_row = new RowDefinition(); + list_caption_row.Height = new GridLength(1.0, GridUnitType.Auto); + content_grid.RowDefinitions.Add(list_caption_row); + Grid.SetRow(apply_grid, 2); + content_grid.Children.Add(apply_grid); + + var list_row = new RowDefinition(); + list_row.Height = new GridLength(1.0, GridUnitType.Auto); + content_grid.RowDefinitions.Add(list_row); + Grid.SetRow(_visualizations_list, 3); + content_grid.Children.Add(_visualizations_list); - // Get generic data of DataType -> apply changed data to DataType - // Add custom UI of inheriting filter var child = create_ui(); + var child_border = new Border(); + child_border.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); + child_border.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); + child_border.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); + child_border.CornerRadius = new CornerRadius(0); + child_border.Margin = new Thickness(_margin, _margin, _margin, _margin); + child_border.Child = child; + + var filter_row = new RowDefinition(); + filter_row.Height = new GridLength(1.0, GridUnitType.Auto); + content_grid.RowDefinitions.Add(filter_row); + Grid.SetRow(child_border, 4); + content_grid.Children.Add(child_border); + + _content.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); + _content.BorderThickness = new Thickness(2.0, 2.0, 2.0, 2.0); + _content.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); + _content.CornerRadius = new CornerRadius(0); + _content.Margin = new Thickness(_margin, _margin, _margin, _margin); + _content.Child = content_grid; - // Attach filter UI to filter list of Filter Editor _modify_ui_filter_list_callback(_content, ListModification.ADD); @@ -173,11 +308,31 @@ public UIElement GetUI() /// Called on creation of filter /// /// - public void ProvideContentDataCallback(List content_metadata) + public void ContentMetadataListCallback(List content_metadata) { - // Update check boxes in content list + if (!_created) + { + Log.Default.Msg(Log.Level.Error, "Creation of content required prior to execution"); + return; + } + + _visualizations_list.Children.Clear(); + foreach (var metadata in content_metadata) + { + var check = new CheckBox(); + check.SetBinding(CheckBox.ContentProperty, metadata.NameBinding); + check.Margin = new Thickness(_margin, _margin, 0.0, 0.0); + check.Tag = metadata.DataUID; + check.Click += click_dirty; + check.SetResourceReference(CheckBox.ForegroundProperty, "Brush_Foreground"); + _visualizations_list.Children.Add(check); + } + } + private void click_dirty(object sender, RoutedEventArgs e) + { + set_filter_dirty(); } #endregion @@ -190,6 +345,24 @@ protected virtual UIElement create_ui() throw new InvalidOperationException("Should be implemented by inheriting class."); } + private void _apply_button_click(object sender, RoutedEventArgs e) + { + var sender_button = sender as Button; + if (sender_button == null) + { + Log.Default.Msg(Log.Level.Error, "Unexpected sender"); + return; + } + sender_button.IsEnabled = false; + _apply_button.SetResourceReference(Button.BackgroundProperty, "Brush_Background"); + } + + protected void set_filter_dirty() + { + _apply_button.IsEnabled = true; + _apply_button.SetResourceReference(Button.BackgroundProperty, "Brush_ApplyDirtyBackground"); + } + #endregion /* ------------------------------------------------------------------*/ @@ -201,17 +374,25 @@ private void event_apply_filter() // call _get_selected_data_callback, modify all data and the call _update_selected_data_callback for all selected contents } - #endregion /* ------------------------------------------------------------------*/ #region private variables - private Grid _content = null; + private const double _margin = 5.0; + + private bool _created = false; + + private Border _content = null; + private RenameLabel _filter_caption = null; + private StackPanel _visualizations_list = null; + private Button _apply_button = null; + private DataManager.UpdateSelectedDataCallback_Delegate _update_selected_data_callback = null; private DataManager.GetGenericDataCallback_Delegate _get_selected_data_callback = null; - private ModifyUIFilterList_Delegate _modify_ui_filter_list_callback = null; + private FilterManager.ModifyUIFilterList_Delegate _modify_ui_filter_list_callback = null; + private FilterManager.DeleteFilterCallback_Delegate _delete_self_callback = null; #endregion } diff --git a/Core/Abstracts/AbstractMenuBar.cs b/Core/Abstracts/AbstractMenuBar.cs index 358932f..039c0c8 100644 --- a/Core/Abstracts/AbstractMenuBar.cs +++ b/Core/Abstracts/AbstractMenuBar.cs @@ -5,7 +5,6 @@ using System; using System.Windows.Navigation; using System.Collections.Generic; -using static Core.GUI.MenubarMain; diff --git a/Core/Abstracts/AbstractVisualization.cs b/Core/Abstracts/AbstractVisualization.cs index d997be0..04e2541 100644 --- a/Core/Abstracts/AbstractVisualization.cs +++ b/Core/Abstracts/AbstractVisualization.cs @@ -5,12 +5,6 @@ using System.Windows; using Core.GUI; using Core.Data; -using System.Windows.Documents; -using System.Windows.Data; -using System.Globalization; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; -using System.Windows.Controls.Primitives; -using System.Windows.Input; diff --git a/Core/Abstracts/AbstractWindow.cs b/Core/Abstracts/AbstractWindow.cs index f5c6af4..00d47b8 100644 --- a/Core/Abstracts/AbstractWindow.cs +++ b/Core/Abstracts/AbstractWindow.cs @@ -14,6 +14,7 @@ using ReadContentMetaData_Type = System.Tuple; using AttachContentMetaData_Type = System.Tuple; +using System.Windows.Data; namespace Core @@ -27,7 +28,7 @@ public abstract class AbstractWindow public delegate List AvailableContents_Delegate(); - public delegate AttachContentMetaData_Type CreateContent_Delegate(int content_uid, string content_type); + public delegate AttachContentMetaData_Type CreateContent_Delegate(int content_uid, string content_type, Binding name_binding); public delegate bool DeleteContent_Delegate(int content_uid); diff --git a/Core/Core.csproj b/Core/Core.csproj index c895d61..fb84f74 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -131,6 +131,7 @@ + diff --git a/Core/Filtering/ColumnSelectionFilter.cs b/Core/Filtering/ColumnSelectionFilter.cs index 8a6a5c5..56a86db 100644 --- a/Core/Filtering/ColumnSelectionFilter.cs +++ b/Core/Filtering/ColumnSelectionFilter.cs @@ -46,6 +46,9 @@ public class Configuration : AbstractFilter.Configuration protected override UIElement create_ui() { var ui = new Grid(); + _Name = "Column Selection"; + + ui.Height = 150; return ui; diff --git a/Core/Filtering/FilterManager.cs b/Core/Filtering/FilterManager.cs index ba59750..0850844 100644 --- a/Core/Filtering/FilterManager.cs +++ b/Core/Filtering/FilterManager.cs @@ -6,6 +6,7 @@ using Core.Utilities; using Core.Filter; using Core.Data; +using static Core.Abstracts.AbstractFilter; @@ -64,6 +65,8 @@ public bool Initialize(DataManager.GetGenericDataCallback_Delegate get_selected_ _timer.Start(); + _content_metadata = new List(); + _get_selected_data_callback = get_selected_data_callback; _update_selected_data_callback = update_selected_data_callback; @@ -97,7 +100,7 @@ public List GetFilterTypeList() foreach (var filter_data in _contents) { var filter_metadata = new FilterListMetadata(); - filter_metadata.ID = id; // for enumeration in combobox + ///filter_metadata.ID = id; // for enumeration in combobox filter_metadata.Name = filter_data.Key.Name; filter_metadata.Type = filter_data.Key; list.Add(filter_metadata); @@ -109,6 +112,13 @@ public List GetFilterTypeList() public void SetModifyUIFilterList(ModifyUIFilterList_Delegate modify_ui_filter_list_callback) { _modify_ui_filter_list_callback = modify_ui_filter_list_callback; + foreach (var filter_data in _contents) + { + foreach (var filter in filter_data.Value) + { + _modify_ui_filter_list_callback(filter.Value.GetUI(), AbstractFilter.ListModification.ADD); + } + } } public bool CreateFilterCallback(Type filter_type) @@ -127,12 +137,12 @@ public bool CreateFilterCallback(Type filter_type) if (_contents.ContainsKey(filter_type)) { var filter = (AbstractFilter)Activator.CreateInstance(filter_type); - if (filter.Initialize(_get_selected_data_callback, _update_selected_data_callback, _modify_ui_filter_list_callback)) + if (filter.Initialize(_get_selected_data_callback, _update_selected_data_callback, _modify_ui_filter_list_callback, DeleteFilterCallback)) { - filter.ProvideContentDataCallback(_content_metadata); if (filter.CreateUI()) { - _contents[filter_type].Add(filter._UID, filter); + filter.ContentMetadataListCallback(_content_metadata); + _contents[filter_type].Add(filter._UID, filter); return true; } else @@ -199,15 +209,34 @@ public bool ApplyConfigurations(string configurations) return false; } - public void ProvideContentDataCallback(List content_metadata) + public void AddContentMetadataCallback(AbstractFilter.ContentMetadata content_metadata) { - _content_metadata = content_metadata; + _content_metadata.Add(content_metadata); + + foreach (var filter_type in _contents) + { + foreach (var filter in filter_type.Value) + { + filter.Value.ContentMetadataListCallback(_content_metadata); + } + } + } + public void DeleteContentMetadataCallback(int data_uid) + { + foreach (var cm in _content_metadata) + { + if (cm.DataUID == data_uid) + { + _content_metadata.Remove(cm); + break; + } + } foreach (var filter_type in _contents) { foreach (var filter in filter_type.Value) { - filter.Value.ProvideContentDataCallback(content_metadata); + filter.Value.ContentMetadataListCallback(_content_metadata); } } } @@ -238,7 +267,9 @@ protected override bool reset_content(AbstractFilter filter_value) /* ------------------------------------------------------------------*/ #region private variables + // Required to provide new filters with content metadata private List _content_metadata = null; + private DataManager.UpdateSelectedDataCallback_Delegate _update_selected_data_callback = null; private DataManager.GetGenericDataCallback_Delegate _get_selected_data_callback = null; private ModifyUIFilterList_Delegate _modify_ui_filter_list_callback = null; diff --git a/Core/Filtering/ValueSelectionFilter.cs b/Core/Filtering/ValueSelectionFilter.cs index db52c4c..cd1a479 100644 --- a/Core/Filtering/ValueSelectionFilter.cs +++ b/Core/Filtering/ValueSelectionFilter.cs @@ -46,6 +46,9 @@ public class Configuration : AbstractFilter.Configuration protected override UIElement create_ui() { var ui = new Grid(); + _Name = "Value Selection"; + + ui.Height = 150; return ui; diff --git a/Core/GUI/MenubarMain.cs b/Core/GUI/MenubarMain.cs index 7d24898..12d1ea6 100644 --- a/Core/GUI/MenubarMain.cs +++ b/Core/GUI/MenubarMain.cs @@ -21,6 +21,7 @@ public class MenubarMain : AbstractMenuBar public enum PredefinedMenuOption { FILE, + VIEW, STYLE, DATA, HELP, @@ -36,6 +37,7 @@ public override bool Initialize() if (base.Initialize()) { add_main_menu("File", PredefinedMenuOption.FILE); + add_main_menu("View", PredefinedMenuOption.VIEW); add_main_menu("Data", PredefinedMenuOption.DATA); add_main_menu("Style", PredefinedMenuOption.STYLE); add_main_menu("Help", PredefinedMenuOption.HELP); diff --git a/Core/GUI/RenameLabel.cs b/Core/GUI/RenameLabel.cs new file mode 100644 index 0000000..a7f528c --- /dev/null +++ b/Core/GUI/RenameLabel.cs @@ -0,0 +1,61 @@ +using System; +using System.Windows.Controls; +using System.Windows; +using System.Windows.Media; +using System.Windows.Documents; +using Core.Utilities; +using Core.Abstracts; +using System.Collections.Generic; +using System.Windows.Input; + + + +/* + * Rename Label + * + */ +namespace Core +{ + namespace GUI + { + public class RenameLabel : TextBox + { + /* ------------------------------------------------------------------*/ + #region public classes + + public RenameLabel() : base() + { + reset(); + this.IsEnabled = true; + this.BorderThickness = new Thickness(0, 0, 0, 0); + + this.KeyUp += (object sender, KeyEventArgs e) => + { + if (e.Key == Key.Enter) + { + reset(); + Keyboard.ClearFocus(); + } + }; + this.LostKeyboardFocus += (object sender, KeyboardFocusChangedEventArgs e) => + { + reset(); + }; + } + + #endregion + + /* ------------------------------------------------------------------*/ + #region private functions + + private void reset() + { + this.Focusable = false; + this.Cursor = Cursors.Arrow; + this.Style = ColorTheme.ContentCaptionStyle(); + } + + #endregion + } + } +} diff --git a/Core/GUI/Windows/WindowBranch.cs b/Core/GUI/Windows/WindowBranch.cs index e8eed02..21ac37d 100644 --- a/Core/GUI/Windows/WindowBranch.cs +++ b/Core/GUI/Windows/WindowBranch.cs @@ -214,8 +214,7 @@ public void ResetRoot() if (_Leaf != null) { - /// Don't do that because this will delete newly added visualizations having the same ID as the previous one: - //_Leaf.ResetLeaf(); + _Leaf.ResetLeaf(); _Leaf = null; } _Orientation = SplitOrientation.None; @@ -418,8 +417,7 @@ private void reset_window() _Children = null; if (_Leaf != null) { - /// Don't do that because this will delete newly added visualizations having the same ID as the previous one: - //_Leaf.ResetLeaf(); + _Leaf.ResetLeaf(); _Leaf = null; } _Orientation = SplitOrientation.None; diff --git a/Core/GUI/Windows/WindowLeaf.cs b/Core/GUI/Windows/WindowLeaf.cs index fd6f170..13cc723 100644 --- a/Core/GUI/Windows/WindowLeaf.cs +++ b/Core/GUI/Windows/WindowLeaf.cs @@ -22,6 +22,7 @@ // Arguments: using ReadContentMetaData_Type = System.Tuple; using ContentCallbacks_Type = System.Tuple; +using System.Windows.Data; namespace Core @@ -79,11 +80,11 @@ public WindowLeaf(WindowBranch parent_branch, bool parent_is_root, ContentCallba } _menu = new MenubarWindow(); - _content_caption = new TextBox(); + _content_caption = new RenameLabel(); + _content_child = new Grid(); _Name = ""; - _content_child = new Grid(); _content_child.SetResourceReference(Grid.BackgroundProperty, "Brush_Background"); _content_child.Name = "grid_" + UniqueID.GenerateString(); @@ -114,7 +115,7 @@ public WindowLeaf(WindowBranch parent_branch, bool parent_is_root, ContentCallba public void CreateContent(int uid, string content_type) { // Call Create Content - var content_metadata = _content_callbacks.Item2(uid, content_type); + var content_metadata = _content_callbacks.Item2(uid, content_type, create_caption_binding()); if (content_metadata != null) { if ((content_metadata.Item1 != UniqueID.InvalidInt) && (content_metadata.Item2 != null)) @@ -133,7 +134,7 @@ public void CreateContent(int uid, string content_type) /// XXX Exclude some content from having the following menu --- Find better solution! if (!((content_type == AbstractVisualization.TypeString_FilterEditor) || (content_type == AbstractVisualization.TypeString_LogConsole))) { - var filter_menu_item = MenubarMain.GetDefaultMenuItem("Open filter editor", open_filter_editor); + var filter_menu_item = MenubarMain.GetDefaultMenuItem("Open Filter Editor", open_filter_editor); List available_child_content = _content_callbacks.Item1(); foreach (var content_data in available_child_content) @@ -196,6 +197,9 @@ public void SetParent(WindowBranch parent_branch, bool parent_is_root) public void ResetLeaf() { delete_content(); + _content_child = null; + _menu = null; + _content_caption = null; base.reset(); } @@ -232,23 +236,6 @@ private Grid create_menu() menu.Style = ColorTheme.ContentMenuBarStyle(); menu_grid.Children.Add(menu); - // Set global menu items before creating menu - _content_caption.IsEnabled = true; - _content_caption.BorderThickness = new Thickness(0, 0, 0, 0); - reset_caption_textbox(); - _content_caption.KeyUp += (object sender, KeyEventArgs e) => - { - if (e.Key == Key.Enter) - { - reset_caption_textbox(); - Keyboard.ClearFocus(); - } - }; - _content_caption.LostKeyboardFocus += (object sender, KeyboardFocusChangedEventArgs e) => - { - reset_caption_textbox(); - }; - var _menu_rename = MenubarMain.GetDefaultMenuItem("Rename"); _menu_rename.Click += (object sender, RoutedEventArgs e) => { @@ -352,19 +339,18 @@ private Grid create_menu() item_content_delete.Name = _item_id_delete_content; item_content_delete.Click += event_menuitem_click; item_content_delete.IsEnabled = false; - _menu.AddMenu(MenubarWindow.PredefinedMenuOption.VIEW, item_content_delete); var item_content_dad = new MenuItem(); item_content_dad.Style = ColorTheme.MenuItemIconStyle("drag-and-drop.png"); item_content_dad.Header = "Content Swap"; - item_content_dad.IsHitTestVisible = false; - item_content_dad.Focusable = false; _menu.AddMenu(MenubarWindow.PredefinedMenuOption.VIEW, item_content_dad); var item_content_dad_text = new MenuItem(); item_content_dad_text.Header = "Drag&Drop [Middle Mouse Button]"; item_content_dad_text.IsEnabled = false; + item_content_dad_text.IsHitTestVisible = false; + item_content_dad_text.Focusable = false; item_content_dad.Items.Add(item_content_dad_text); // ----- DATA ----------------------------------------- @@ -383,7 +369,7 @@ private void event_menuitem_click(object sender, RoutedEventArgs e) var sender_content = sender as MenuItem; if (sender_content == null) { - Log.Default.Msg(Log.Level.Error, "Expected menu item"); + Log.Default.Msg(Log.Level.Error, "Unexpected sender"); return; } @@ -463,13 +449,6 @@ private bool open_filter_editor() return true; } - private void reset_caption_textbox() - { - _content_caption.Focusable = false; - _content_caption.Cursor = Cursors.Arrow; - _content_caption.Style = ColorTheme.ContentCaptionStyle(); - } - /// /// Delete attached content permanently. /// @@ -589,6 +568,15 @@ private string conform_name(string name) return conform_name; } + private Binding create_caption_binding() + { + var caption_binding = new Binding("Text"); + caption_binding.Mode = BindingMode.TwoWay; + caption_binding.Source = _content_caption; + return caption_binding; + /// _filter_caption.SetBinding(TextBlock.TextProperty, caption_binding); + } + #endregion /* ------------------------------------------------------------------*/ @@ -596,7 +584,7 @@ private string conform_name(string name) private Grid _content_child = null; private MenubarWindow _menu = null; - private TextBox _content_caption = null; + private RenameLabel _content_caption = null; private readonly string _item_id_hori_top = "item_horizontal_top_" + UniqueID.GenerateString(); private readonly string _item_id_hori_bottom = "item_horizontal_bottom_" + UniqueID.GenerateString(); diff --git a/Core/GUI/Windows/WindowManager.cs b/Core/GUI/Windows/WindowManager.cs index 0a819d9..54fb288 100644 --- a/Core/GUI/Windows/WindowManager.cs +++ b/Core/GUI/Windows/WindowManager.cs @@ -93,38 +93,62 @@ public bool ApplyConfigurations(string configurations) return false; } + public override void AttachMenu(MenubarMain menu_bar) + { + var default_item = MenubarMain.GetDefaultMenuItem("Load Default", menu_create_default); + menu_bar.AddMenu(MenubarMain.PredefinedMenuOption.VIEW, default_item); + + var clear_item = MenubarMain.GetDefaultMenuItem("Clear All", menu_clear_all); + menu_bar.AddMenu(MenubarMain.PredefinedMenuOption.VIEW, clear_item); + } + + #endregion + + /* ------------------------------------------------------------------*/ + #region private functions + + /// + /// Remove all windows and their content. + /// + private bool menu_clear_all() + { + _window_root.ResetRoot(); + return true; + } + /// /// Load default window configuration. /// - public void CreateDefault() + private bool menu_create_default() { if (!_initialized) { Log.Default.Msg(Log.Level.Error, "Initialization required prior to execution"); - return; + return false; } + _window_root.ResetRoot(); + /* - _______________________________ - |Data Viewer | | - | | | - | | | - |____________|________________| - |Log Console | - |_____________________________| + ___________________________________ + |Data Viewer |Lines |Filter | + | | | | + | | | | + |____________|___________| | + |Log Console | | + |________________________|________| */ - _window_root.Split(WindowBranch.SplitOrientation.Horizontal, WindowBranch.ChildLocation.None, 0.7); - _window_root._Children.Item1.Split(WindowBranch.SplitOrientation.Vertical, WindowBranch.ChildLocation.None, 0.31); - _window_root._Children.Item1._Children.Item1._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_DataViewer); - _window_root._Children.Item1._Children.Item2._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_SciChartLines); - _window_root._Children.Item2._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_LogConsole); + _window_root.Split(WindowBranch.SplitOrientation.Vertical, WindowBranch.ChildLocation.None, 0.8); + _window_root._Children.Item1.Split(WindowBranch.SplitOrientation.Horizontal, WindowBranch.ChildLocation.None, 0.7); + _window_root._Children.Item2._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_FilterEditor); + _window_root._Children.Item1._Children.Item1.Split(WindowBranch.SplitOrientation.Vertical, WindowBranch.ChildLocation.None, 0.31); + _window_root._Children.Item1._Children.Item1._Children.Item1._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_DataViewer); + _window_root._Children.Item1._Children.Item1._Children.Item2._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_SciChartLines); + _window_root._Children.Item1._Children.Item2._Leaf.CreateContent(UniqueID.InvalidInt, AbstractVisualization.TypeString_LogConsole); + + return true; } - #endregion - - /* ------------------------------------------------------------------*/ - #region private functions - /// /// Traverse window tree in breadth first order to gather all configurations recursively. /// diff --git a/Core/resources/color-themes/Dark.xaml b/Core/resources/color-themes/Dark.xaml index 54873bb..445f0f8 100644 --- a/Core/resources/color-themes/Dark.xaml +++ b/Core/resources/color-themes/Dark.xaml @@ -25,4 +25,6 @@ + + \ No newline at end of file diff --git a/Core/resources/color-themes/LightBlue.xaml b/Core/resources/color-themes/LightBlue.xaml index d64b319..a40cf75 100644 --- a/Core/resources/color-themes/LightBlue.xaml +++ b/Core/resources/color-themes/LightBlue.xaml @@ -24,5 +24,7 @@ - + + + \ No newline at end of file diff --git a/SciChartInterface/Abstracts/AbstractSciChartSeries.cs b/SciChartInterface/Abstracts/AbstractSciChartSeries.cs index 11b949f..fb996c2 100644 --- a/SciChartInterface/Abstracts/AbstractSciChartSeries.cs +++ b/SciChartInterface/Abstracts/AbstractSciChartSeries.cs @@ -113,7 +113,7 @@ public override bool CreateUI() }, new LegendModifier() { - IsEnabled = true, + IsEnabled = false, ShowLegend = true, } ); diff --git a/Visualizations/ContentManager.cs b/Visualizations/ContentManager.cs index 4330708..ba6ebb1 100644 --- a/Visualizations/ContentManager.cs +++ b/Visualizations/ContentManager.cs @@ -9,6 +9,7 @@ using Core.GUI; using Core.Data; using Core.Filter; +using System.Windows.Data; @@ -231,7 +232,7 @@ public List AvailableContentsCallback() /// The string ID of the content if present. /// Using string for content type to allow cross project compatibility. /// Tuple of content ID and the WPF Control element holding the actual content. - public AttachContentMetaData_Type CreateContentCallback(int content_uid, string content_type) + public AttachContentMetaData_Type CreateContentCallback(int content_uid, string content_type, Binding name_binding) { if (!_initialized) { @@ -269,6 +270,14 @@ public AttachContentMetaData_Type CreateContentCallback(int content_uid, string _contents[type].Add(temp_uid, new_content); } } + + // Only add content with valid data uid to filter list + int data_uid = _contents[type][temp_uid]._DataUID; + if (data_uid != UniqueID.InvalidInt) { + var content_metadata = new AbstractFilter.ContentMetadata() { NameBinding = name_binding, DataUID = data_uid }; + _filtermanager.AddContentMetadataCallback(content_metadata); + } + return new AttachContentMetaData_Type(temp_uid, _contents[type][temp_uid].GetUI(), _contents[type][temp_uid].AttachMenu); } else @@ -295,7 +304,14 @@ public bool DeleteContentCallback(int content_uid) { if (content_types.Value.ContainsKey(content_uid)) { - _datamanager.UnregisterDataCallback(content_types.Value[content_uid]._DataUID); + // Filter Editor requires special handling + if (content_types.Key == typeof(WPF_FilterEditor)) + { + /// XXX TODO Delete all filters? + } + int data_uid = content_types.Value[content_uid]._DataUID; + _filtermanager.DeleteContentMetadataCallback(data_uid); + _datamanager.UnregisterDataCallback(data_uid); content_types.Value[content_uid].Terminate(); return content_types.Value.Remove(content_uid); } @@ -312,10 +328,15 @@ public bool DeleteContentCallback(int content_uid) /// /// Reset specific content (only used in AbstractRegisterService) /// - /// + /// /// protected override bool reset_content(AbstractVisualization content_value) { + // Filter Editor requires special handling + if (content_value.GetType() == typeof(WPF_FilterEditor)) + { + /// XXX TODO Delete all filters? + } _datamanager.UnregisterDataCallback(content_value._DataUID); return content_value.Terminate(); } diff --git a/Visualizations/Visualizations/WPF_FilterEditor.cs b/Visualizations/Visualizations/WPF_FilterEditor.cs index d5a524d..892d10c 100644 --- a/Visualizations/Visualizations/WPF_FilterEditor.cs +++ b/Visualizations/Visualizations/WPF_FilterEditor.cs @@ -1,19 +1,14 @@ using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Controls; -using Core.Utilities; -using System.Windows.Media; -using System.Windows.Documents; -using System.Collections.Generic; -using Core.Data; + using Core.Abstracts; -using Visualizations.WPFInterface; -using Core.GUI; using Core.Filter; -using System.Globalization; -using System.Windows.Documents; -using System.Windows.Data; -using System.Globalization; +using Core.GUI; +using Core.Utilities; + +using Visualizations.WPFInterface; @@ -61,88 +56,69 @@ public override bool CreateUI() _add_filter_list.IsEditable = false; _add_filter_list.DisplayMemberPath = "Name"; _add_filter_list.SelectedIndex = 0; - + _add_filter_list.Margin = new Thickness(0.0, 2.0, 2.0, 2.0); var add_button = new Button(); - string label = " Add Filter "; - add_button.Content = label; - var formattedText = new FormattedText(label, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Verdana"), add_button.FontSize, Brushes.Black); - var text_width = formattedText.Width; - add_button.Width = text_width; + add_button.Content = " Add Filter "; add_button.Click += event_apply_button; + add_button.Margin = new Thickness(2.0, 4.0, 2.0, 4.0); - /* - add_button.FontWeight = FontWeights.Bold; - add_button.SetResourceReference(Button.ForegroundProperty, "Brush_Foreground"); - - // Invert background color on mouse over - var button_style = new Style(); - button_style.TargetType = typeof(Button); + _list_scrolling = new ScrollViewer(); + _list_scrolling.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; + _list_scrolling.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; + _list_scrolling.SetResourceReference(ScrollViewer.BackgroundProperty, "Brush_Background"); + _list_scrolling.SetResourceReference(ScrollViewer.ForegroundProperty, "Brush_Foreground"); + _list_scrolling.PreviewMouseWheel += event_scrollviewer_mousewheel; - Setter setter_background = new Setter(); - setter_background.Property = Button.BackgroundProperty; - setter_background.Value = new DynamicResourceExtension("Brush_Background"); - button_style.Setters.Add(setter_background); - - var border = new FrameworkElementFactory(typeof(Border)); - - var button_binding = new Binding("Background"); - button_binding.Mode = BindingMode.TwoWay; - button_binding.Source = add_button; - border.SetBinding(Border.BackgroundProperty, button_binding); - - var control_template = new ControlTemplate(); - control_template.TargetType = typeof(Button); - control_template.VisualTree = border; - - Trigger trigger = new Trigger(); - trigger.Property = Button.IsMouseOverProperty; - trigger.Value = true; - - Setter setter_trigger_b = new Setter(); - setter_trigger_b.Property = Button.BackgroundProperty; - setter_trigger_b.Value = new DynamicResourceExtension("Brush_Foreground"); - trigger.Setters.Add(setter_trigger_b); - - control_template.Triggers.Add(trigger); - - Setter setter_template = new Setter(); - setter_template.Property = Button.TemplateProperty; - setter_template.Value = control_template; + _filter_list = new StackPanel(); + _list_scrolling.Content = _filter_list; - button_style.Setters.Add(setter_template); - add_button.Style = button_style; - */ + var note = new TextBlock(); + note.Text = "Filters are applied sequentially from top to bottom."; + note.SetResourceReference(TextBlock.BackgroundProperty, "Brush_Background"); + note.SetResourceReference(TextBlock.ForegroundProperty, "Brush_Foreground"); + note.Margin = new Thickness(5.0, 5.0, 5.0, 5.0); - var filter_list_scrolling = new ScrollViewer(); - filter_list_scrolling.VerticalScrollBarVisibility = ScrollBarVisibility.Auto; - filter_list_scrolling.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto; - filter_list_scrolling.SetResourceReference(ScrollViewer.BackgroundProperty, "Brush_Background"); - filter_list_scrolling.SetResourceReference(ScrollViewer.ForegroundProperty, "Brush_Foreground"); - filter_list_scrolling.PreviewMouseWheel += event_scrollviewer_mousewheel; + var note_border = new Border(); + note_border.Child = note; + note_border.SetResourceReference(Border.BackgroundProperty, "Brush_Background"); + note_border.BorderThickness = new Thickness(0.0, 0.0, 0.0, 2.0); + note_border.SetResourceReference(Border.BorderBrushProperty, "Brush_Foreground"); + note_border.CornerRadius = new CornerRadius(0); - _filter_list = new StackPanel(); - filter_list_scrolling.Content = _filter_list; + note_border.Margin = new Thickness(0.0, 0.0, 0.0, 5.0); - var top_grid = new Grid(); + var caption_grid = new Grid(); + var add_grid = new Grid(); var column_label = new ColumnDefinition(); - column_label.Width = new GridLength(text_width); - top_grid.ColumnDefinitions.Add(column_label); + column_label.Width = new GridLength(0.0, GridUnitType.Auto); + add_grid.ColumnDefinitions.Add(column_label); Grid.SetColumn(add_button, 0); - top_grid.Children.Add(add_button); + add_grid.Children.Add(add_button); var column_list = new ColumnDefinition(); column_list.Width = new GridLength(1.0, GridUnitType.Star); - top_grid.ColumnDefinitions.Add(column_list); + add_grid.ColumnDefinitions.Add(column_list); Grid.SetColumn(_add_filter_list, 1); - top_grid.Children.Add(_add_filter_list); + add_grid.Children.Add(_add_filter_list); + var top_row = new RowDefinition(); + top_row.Height = new GridLength(1.0, GridUnitType.Star); + caption_grid.RowDefinitions.Add(top_row); + Grid.SetRow(add_grid, 0); + caption_grid.Children.Add(add_grid); - DockPanel.SetDock(top_grid, System.Windows.Controls.Dock.Top); - _Content.Children.Add(top_grid); - _Content.Children.Add(filter_list_scrolling); + var row_note = new RowDefinition(); + row_note.Height = new GridLength(1.0, GridUnitType.Star); + caption_grid.RowDefinitions.Add(row_note); + Grid.SetRow(note_border, 1); + caption_grid.Children.Add(note_border); + + DockPanel.SetDock(caption_grid, System.Windows.Controls.Dock.Top); + _Content.Children.Add(caption_grid); + _Content.Children.Add(_list_scrolling); _timer.Stop(); @@ -165,6 +141,12 @@ public override bool Terminate() { if (_initialized) { + _add_filter_list = null; + _list_scrolling = null; + + _filter_list.Children.Clear(); + _filter_list = null; + _create_filter_callback = null; _initialized = false; @@ -199,6 +181,7 @@ public void ModifyUIFilterList(UIElement element, AbstractFilter.ListModificatio case (AbstractFilter.ListModification.ADD): { _filter_list.Children.Add(element); + _list_scrolling.ScrollToBottom(); } break; case (AbstractFilter.ListModification.DELETE): @@ -254,6 +237,7 @@ private void event_scrollviewer_mousewheel(object sender, System.Windows.Input.M #region private variables private ComboBox _add_filter_list = null; + private ScrollViewer _list_scrolling = null; private StackPanel _filter_list = null; private FilterManager.CreateFilterCallback_Delegate _create_filter_callback = null; diff --git a/Visualizations/Visualizations/WPF_LogConsole.cs b/Visualizations/Visualizations/WPF_LogConsole.cs index 6c1c645..8095db5 100644 --- a/Visualizations/Visualizations/WPF_LogConsole.cs +++ b/Visualizations/Visualizations/WPF_LogConsole.cs @@ -15,11 +15,6 @@ /* * Log Window Content * - * Default window content set in WindowManager.CreateDefault() - * Control Hierarchy: ScrollViewer(Content) -> TextBlick(_text_block) - * - * TODO Optimize performance for huge amount of messages -> render only visible lines (required full copy of all messages?) - * */ namespace Visualizations { @@ -125,7 +120,7 @@ public void LogListener(List msglist) return; } _text_block.Inlines.Add(run); - scroll_bottom(); + _Content.ScrollToBottom(); } } @@ -160,16 +155,6 @@ private void event_scrollviewer_mousewheel(object sender, System.Windows.Input.M e.Handled = true; } - protected void set_scroll_background(string background_color_resource_name) - { - _Content.SetResourceReference(ScrollViewer.BackgroundProperty, background_color_resource_name); - } - - protected void scroll_bottom() - { - _Content.ScrollToBottom(); - } - #endregion /* ------------------------------------------------------------------*/ diff --git a/WPFApplication/MainWindow.xaml.cs b/WPFApplication/MainWindow.xaml.cs index 993021c..8317501 100644 --- a/WPFApplication/MainWindow.xaml.cs +++ b/WPFApplication/MainWindow.xaml.cs @@ -180,16 +180,17 @@ public bool initialize() _configurationservice.RegisterConfiguration(_winmanager._Name, _winmanager.CollectConfigurations, _winmanager.ApplyConfigurations); _configurationservice.RegisterConfiguration(_colortheme._Name, _colortheme.CollectConfigurations, _colortheme.ApplyConfigurations); - loading_progress.SetValue(40); + loading_progress.SetValue(50); // Attach all main menu options (order dependent!) _contentmanager.AttachMenu(_menubar); _configurationservice.AttachMenu(_menubar); _colortheme.AttachMenu(_menubar); + _winmanager.AttachMenu(_menubar); _menubar.AddSeparator(MenubarMain.PredefinedMenuOption.FILE); _menubar.AddMenu(MenubarMain.PredefinedMenuOption.FILE, MenubarMain.GetDefaultMenuItem("Exit", exit_app_click)); - loading_progress.SetValue(50); + loading_progress.SetValue(60); // Attach main menu bar to content _menubar_element.Children.Clear(); @@ -200,24 +201,21 @@ public bool initialize() _subwindows_element.Children.Add(_winmanager.AttachUI()); _subwindows_element.UpdateLayout(); - loading_progress.SetValue(60); + loading_progress.SetValue(70); // Evaluate previously parsed command line arguments _arguments.Evaluate(); - loading_progress.SetValue(70); - - // Load default window configuration - _winmanager.CreateDefault(); - loading_progress.SetValue(80); + /// DEBUG /// Provide example data for detached mode if (_standalone) { var sample_data = TestData.Generate(); _contentmanager.UpdateInputData(sample_data); } + /// DEBUG loading_progress.SetValue(90);