diff --git a/BeWo/BeWo.csproj b/BeWo/BeWo.csproj index 42093a7fa..0576f9bad 100644 --- a/BeWo/BeWo.csproj +++ b/BeWo/BeWo.csproj @@ -173,6 +173,7 @@ + @@ -187,6 +188,9 @@ AiPromptbausteinButton.xaml + + AiPromptbausteinLibraryControl.xaml + AiPromptbausteinActionResultView.xaml @@ -320,6 +324,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/BeWo/Services/BeWoWindowService.cs b/BeWo/Services/BeWoWindowService.cs index efed9b5cc..801004205 100644 --- a/BeWo/Services/BeWoWindowService.cs +++ b/BeWo/Services/BeWoWindowService.cs @@ -139,8 +139,8 @@ namespace BeWo.Services var control = new AiPromptbausteinComplexSelectionView(viewModel); var options = new BeWoWindowOptions() { - Height = 400, - Width = 600 + Height = 600, + Width = 900 }; Show("KI Promptbaustein Auswahl", control, viewModel, options); } diff --git a/BeWo/Styles/DataTemplates/DataTemplates.xaml b/BeWo/Styles/DataTemplates/DataTemplates.xaml index 29a03e93f..cf1d155c3 100644 --- a/BeWo/Styles/DataTemplates/DataTemplates.xaml +++ b/BeWo/Styles/DataTemplates/DataTemplates.xaml @@ -10,7 +10,7 @@ x:Key="ai_promptbaustein_folder_itemtemplate" DataType="{x:Type vm:AiPromptbausteinFolderVM}" ItemsSource="{Binding Path=SubFolders.VMList}"> - + @@ -33,10 +33,12 @@ Grid.Column="1" Height="21" Margin="0,0,0,0" - Padding="0,3,0,0" + Padding="0,0,0,0" + BorderThickness="0" + VerticalAlignment="Center" Background="Transparent" - BorderThickness="0" + Cursor="Arrow" Focusable="False" FontSize="12" diff --git a/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml b/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml new file mode 100644 index 000000000..b5981bf7b --- /dev/null +++ b/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml @@ -0,0 +1,811 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + (i) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Prompts/Routinen angelegt. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Prompts angelegt. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Hier sind noch keine Routinen angelegt. + + + + + + + + + + + + + + + + + + diff --git a/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml.cs b/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml.cs new file mode 100644 index 000000000..a28ec7136 --- /dev/null +++ b/BeWo/View/Controls/AI/AiPromptbausteinLibraryControl.xaml.cs @@ -0,0 +1,202 @@ +using BeWo.ViewModel; +using DevExpress.Xpf.Editors; +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; + +namespace BeWo.View.Controls.AI +{ + /// + /// Gemeinsame Promptbaustein-Bibliothek (TreeView + GridSplitter + TabControl), + /// genutzt von AiPromptbausteinComplexTreeView und AiPromptbausteinComplexSelectionView. + /// Der DataContext wird vom Host geerbt und muss IAiPromptbausteinComplexViewModel implementieren. + /// + public partial class AiPromptbausteinLibraryControl : UserControl + { + public AiPromptbausteinLibraryControl() + { + InitializeComponent(); + } + + private IAiPromptbausteinComplexViewModel ViewModel => DataContext as IAiPromptbausteinComplexViewModel; + + public static readonly DependencyProperty PromptActivatedCommandProperty = + DependencyProperty.Register("PromptActivatedCommand", typeof(ICommand), + typeof(AiPromptbausteinLibraryControl), new PropertyMetadata(null)); + + public static readonly DependencyProperty RoutineActivatedCommandProperty = + DependencyProperty.Register("RoutineActivatedCommand", typeof(ICommand), + typeof(AiPromptbausteinLibraryControl), new PropertyMetadata(null)); + + /// + /// Wird bei Doppelklick auf einen Prompt ausgeführt (Verwaltung: Bearbeiten, Auswahl: Senden). + /// + public ICommand PromptActivatedCommand + { + get { return (ICommand)GetValue(PromptActivatedCommandProperty); } + set { SetValue(PromptActivatedCommandProperty, value); } + } + + /// + /// Wird bei Doppelklick auf eine Routine ausgeführt (Verwaltung: Bearbeiten, Auswahl: Senden). + /// + public ICommand RoutineActivatedCommand + { + get { return (ICommand)GetValue(RoutineActivatedCommandProperty); } + set { SetValue(RoutineActivatedCommandProperty, value); } + } + + /// + /// Setzt die initiale Selektion zurück (erstes TreeViewItem an- und wieder abwählen), + /// damit beim Öffnen kein Ordner vorselektiert ist. + /// + public void ResetInitialSelection() + { + if (treeView.ItemContainerGenerator.ContainerFromIndex(0) is TreeViewItem item) + { + item.IsSelected = true; + item.IsSelected = false; + } + + listBoxEdit1.UnSelectAll(); + } + + private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) + { + TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); + + if (treeViewItem != null) + { + treeViewItem.Focus(); + e.Handled = true; + } + else + { + e.Handled = true; + + if (ViewModel?.SelectedFolder == null) + return; + + _LastTreeViewItem.IsSelected = false; + + treeView.Focus(); + } + } + + static T VisualUpwardSearch(DependencyObject source) where T : DependencyObject + { + while (source != null && !(source is T)) + source = VisualTreeHelper.GetParent(source); + + return source as T; + } + + private void treeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + if (ViewModel is null) + return; + + ViewModel.SelectedFolder = treeView.SelectedValue as AiPromptbausteinFolderVM; + } + + private void Grid_PreviewMouseDown(object sender, MouseButtonEventArgs e) + { + TreeViewItem treeViewItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); + + if (treeViewItem is null) + { + treeView.Focus(); + e.Handled = true; + return; + } + + if (e.ClickCount == 2) + { + if (!ViewModel.OpenEditFolderDialogCommand.CanExecute(null)) + return; + + ViewModel.OpenEditFolderDialogCommand.Execute(null); + e.Handled = true; + } + } + + private TreeViewItem _LastTreeViewItem; + private void treeView_Selected(object sender, RoutedEventArgs e) + { + _LastTreeViewItem = e.OriginalSource as TreeViewItem; + } + + private void treeView_ContextMenuOpening(object sender, ContextMenuEventArgs e) + { + ViewModel?.UpdateFolderCommands(); + } + + private void ListBox_ContextMenuOpening(object sender, ContextMenuEventArgs e) + { + ViewModel?.UpdatePromptCommands(); + } + + private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) + { + Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); + e.Handled = true; + } + + private void Grid_PreviewMouseDown_1(object sender, MouseButtonEventArgs e) + { + var cmd = PromptActivatedCommand; + + if (cmd == null || !cmd.CanExecute(null)) + return; + + if (e.ClickCount == 2) + { + cmd.Execute(null); + e.Handled = true; + } + } + + private void Grid_PreviewMouseDown_2(object sender, MouseButtonEventArgs e) + { + var cmd = RoutineActivatedCommand; + + if (cmd == null || !cmd.CanExecute(null)) + return; + + if (e.ClickCount == 2) + { + cmd.Execute(null); + e.Handled = true; + } + } + + private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (e.OriginalSource is TabControl) + { + listBoxEdit1.UnSelectAll(); + listBoxEdit2.UnSelectAll(); + listBoxEdit3.UnSelectAll(); + } + } + + private void listBoxEdit3_PreviewMouseDown(object sender, MouseButtonEventArgs e) + { + if (!(e.OriginalSource is UIElement)) + { + return; + } + + ListBoxItem listBoxItem = VisualUpwardSearch(e.OriginalSource as DependencyObject); + + if (listBoxItem is null) + { + ((ListBoxEdit)sender).Focus(); + e.Handled = true; + return; + } + } + } +} diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml index cd0d2b397..f9fc7ff70 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml @@ -1,12 +1,12 @@ - - - + TargetType="ListBoxItem" /> + + + + + + + + + + + + + + + + + + + + + + + + (i) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33,7 +272,6 @@ - - - - - - - - - - - - - - - - - - - - - - - (i) - - - - - - + + + + + + + + + + + + + + Keine Favoriten vorhanden. + + + + + + + + + + + + + Keine Prompt-Favoriten vorhanden. + + + + + + + + + + + + + Keine Routinen-Favoriten vorhanden. + + + + - - - - - diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs index 770622cda..6ecdc58d3 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionFavoritenView.xaml.cs @@ -1,25 +1,15 @@ -using BeWo.ViewModel.View.AI; using BeWo.ViewModel; -using System; -using System.Collections.Generic; +using BeWo.ViewModel.View.AI; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; namespace BeWo.View.Detail.AI { /// - /// Interaktionslogik für AiPromptbausteinComplexSelectionView.xaml + /// Interaktionslogik für AiPromptbausteinComplexSelectionFavoritenView.xaml + /// Reine Auswahl-Ansicht der Favoriten (keine Bearbeitung) — ein Klick auf einen Eintrag sendet sofort. /// public partial class AiPromptbausteinComplexSelectionFavoritenView : UserControl { @@ -36,17 +26,27 @@ namespace BeWo.View.Detail.AI ViewModel.InitVMList(); listBoxEdit1.UnSelectAll(); + listBoxEdit2.UnSelectAll(); + listBoxEdit3.UnSelectAll(); }; } - private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) + private void Item_MouseUp(object sender, MouseButtonEventArgs e) { - Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); - e.Handled = true; - } + if (e.ChangedButton != MouseButton.Left) + return; + + // Klick auf den (i)-Hyperlink soll nur den Link öffnen, nicht senden + if ((e.OriginalSource as FrameworkElement)?.Name == "infobox") + return; + + var vm = (sender as FrameworkElement)?.DataContext as AbstractBaseVM; + + if (vm is null) + return; + + ViewModel.SelectedItem = vm; - private void Grid_MouseUp(object sender, MouseButtonEventArgs e) - { if (!ViewModel.SendCommand.CanExecute(null)) return; @@ -54,19 +54,20 @@ namespace BeWo.View.Detail.AI e.Handled = true; } - private void Grid_MouseEnter(object sender, MouseEventArgs e) + private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e) { - var grid = sender as Grid; + if (e.OriginalSource is TabControl) + { + listBoxEdit1.UnSelectAll(); + listBoxEdit2.UnSelectAll(); + listBoxEdit3.UnSelectAll(); + } + } - if (grid is null) - return; - - var vm = grid.DataContext as AiPromptbausteinPromptVM; - - if (vm is null) - return; - - ViewModel.SelectedItem = vm; - } - } + private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) + { + Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri)); + e.Handled = true; + } + } } diff --git a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml index 34211b99f..6e59c3e4d 100644 --- a/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml +++ b/BeWo/View/Detail/AI/AiPromptbausteinComplexSelectionView.xaml @@ -1,714 +1,48 @@ - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (i) - - - - - - - - - Bearbeitet vor x Minuten - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hier sind noch keine Prompts/Routinen angelegt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hier sind noch keine Prompts angelegt. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Hier sind noch keine Routinen angelegt. - - - - - - +