using System; using System.ComponentModel; using System.Windows; using System.Windows.Input; using System.Windows.Media.Animation; using System.Windows.Controls; using Wox.Core.Plugin; using Wox.Core.Resource; using Wox.Core.UserSettings; using Wox.Helper; using Wox.ViewModel; using Screen = System.Windows.Forms.Screen; using ContextMenu = System.Windows.Forms.ContextMenu; using MenuItem = System.Windows.Forms.MenuItem; using NotifyIcon = System.Windows.Forms.NotifyIcon; namespace Wox { public partial class MainWindow { #region Private Fields private readonly Storyboard _progressBarStoryboard = new Storyboard(); private Settings _settings; private NotifyIcon _notifyIcon; private MainViewModel _viewModel; #endregion public MainWindow(Settings settings, MainViewModel mainVM) { InitializeComponent(); DataContext = mainVM; _viewModel = mainVM; _settings = settings; } public MainWindow() { InitializeComponent(); } private void OnClosing(object sender, CancelEventArgs e) { _notifyIcon.Visible = false; _viewModel.Save(); } private void OnLoaded(object sender, RoutedEventArgs _) { InitProgressbarAnimation(); WindowIntelopHelper.DisableControlBox(this); ThemeManager.Instance.ChangeTheme(_settings.Theme); InitializeNotifyIcon(); } private void InitializeNotifyIcon() { _notifyIcon = new NotifyIcon { Text = Infrastructure.Constant.Wox, Icon = Properties.Resources.app, Visible = true }; _notifyIcon.Click += (o, e) => Visibility = Visibility.Visible; var open = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTrayOpen")); open.Click += (o, e) => Visibility = Visibility.Visible; var setting = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTraySettings")); setting.Click += (o, e) => App.API.OpenSettingDialog(); var exit = new MenuItem(InternationalizationManager.Instance.GetTranslation("iconTrayExit")); exit.Click += (o, e) => Close(); MenuItem[] childen = { open, setting, exit }; _notifyIcon.ContextMenu = new ContextMenu(childen); } private void InitProgressbarAnimation() { var da = new DoubleAnimation(ProgressBar.X2, ActualWidth + 100, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); var da1 = new DoubleAnimation(ProgressBar.X1, ActualWidth, new Duration(new TimeSpan(0, 0, 0, 0, 1600))); Storyboard.SetTargetProperty(da, new PropertyPath("(Line.X2)")); Storyboard.SetTargetProperty(da1, new PropertyPath("(Line.X1)")); _progressBarStoryboard.Children.Add(da); _progressBarStoryboard.Children.Add(da1); _progressBarStoryboard.RepeatBehavior = RepeatBehavior.Forever; ProgressBar.BeginStoryboard(_progressBarStoryboard); _viewModel.ProgressBarVisibility = Visibility.Hidden; } private void OnMouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) DragMove(); } private void OnPreviewMouseButtonDown(object sender, MouseButtonEventArgs e) { if (sender != null && e.OriginalSource != null) { var r = (ResultListBox)sender; var d = (DependencyObject)e.OriginalSource; var item = ItemsControl.ContainerFromElement(r, d) as ListBoxItem; var result = (ResultViewModel)item?.DataContext; if (result != null) { if (e.ChangedButton == MouseButton.Left) { _viewModel.OpenResultCommand.Execute(null); } else if (e.ChangedButton == MouseButton.Right) { _viewModel.LoadContextMenuCommand.Execute(null); } } } } private void OnDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { // Note that you can have more than one file. string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); if (files[0].ToLower().EndsWith(".wox")) { PluginManager.InstallPlugin(files[0]); } else { MessageBox.Show(InternationalizationManager.Instance.GetTranslation("invalidWoxPluginFileFormat")); } } e.Handled = false; } private void OnPreviewDragOver(object sender, DragEventArgs e) { e.Handled = true; } private void OnContextMenusForSettingsClick(object sender, RoutedEventArgs e) { App.API.OpenSettingDialog(); } private void OnDeactivated(object sender, EventArgs e) { if (_settings.HideWhenDeactive) { Hide(); } } private void OnQueryVisible(object sender, DependencyPropertyChangedEventArgs e) { var visible = (bool)e.NewValue; if (visible) { // the Focusable and the IsVisible both needs to be true when set focus // logical is set in xaml QueryTextBox.Focus(); if (_viewModel.QueryTextSelected) { QueryTextBox.SelectAll(); _viewModel.QueryTextSelected = false; } } } private void OnQueryChanged(object sender, TextChangedEventArgs e) { QueryTextBox.CaretIndex = QueryTextBox.Text.Length; } private void OnMainWindowVisible(object sender, DependencyPropertyChangedEventArgs e) { var visible = (bool)e.NewValue; if (visible) { SetWindowPosition(); _settings.ActivateTimes++; } } private bool _startup = true; private void SetWindowPosition() { if (!_settings.RememberLastLaunchLocation && !_startup) { Left = WindowLeft(); Top = WindowTop(); } else { _startup = false; } } /// // used to set correct position on windows first startup // since the actual width and actual height will be avaiable after this event /// private void OnSizeChanged(object sender, SizeChangedEventArgs e) { Left = WindowLeft(); Top = WindowTop(); } private double WindowLeft() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowIntelopHelper.TransformPixelsToDIP(this, screen.WorkingArea.X, 0); var dip2 = WindowIntelopHelper.TransformPixelsToDIP(this, screen.WorkingArea.Width, 0); var left = (dip2.X - ActualWidth) / 2 + dip1.X; return left; } private double WindowTop() { var screen = Screen.FromPoint(System.Windows.Forms.Cursor.Position); var dip1 = WindowIntelopHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Y); var dip2 = WindowIntelopHelper.TransformPixelsToDIP(this, 0, screen.WorkingArea.Height); var top = (dip2.Y - QueryTextBox.ActualHeight) / 4 + dip1.Y; return top; } /// /// Register up and down key /// todo: any way to put this in xaml ? /// private void OnKeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Down) { _viewModel.SelectNextItemCommand.Execute(null); e.Handled = true; } else if (e.Key == Key.Up) { _viewModel.SelectPrevItemCommand.Execute(null); e.Handled = true; } } } }