Beispiel #1
0
        public static void AdjustForDpiScaling([NotNull] this Control control)
        {
            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            if (!DpiUtil.IsNonStandard)
            {
                return;
            }

            var queue = new Queue <Control>();

            queue.Enqueue(control);

            while (queue.Count != 0)
            {
                var next = queue.Dequeue();

                // NOTE we can't automatically scale TreeView or ListView here as
                // adjustment must be done before images are added to the
                // ImageList otherwise they're all removed.

                switch (next)
                {
                case ButtonBase button:
                {
                    if (button.Image != null)
                    {
                        button.Image = DpiUtil.Scale(button.Image);
                    }

                    break;
                }

                case PictureBox pictureBox:
                {
                    if (pictureBox.Image != null)
                    {
                        pictureBox.Image = DpiUtil.Scale(pictureBox.Image);
                    }

                    break;
                }

                case TabControl tabControl:
                {
                    tabControl.Padding = DpiUtil.Scale(tabControl.Padding);
                    EnqueueChildren();
                    break;
                }

                default:
                {
                    if (next is TextBoxBase || next is UpDownBase)
                    {
                        // BUG: looks like a bug in WinForms - control's margin gets scaled beyond expectations
                        // see https://github.com/gitextensions/gitextensions/issues/5098
                        DpiUtil.ScaleDefaultMargins(next);
                    }

                    EnqueueChildren();
                    break;
                }
                }

                void EnqueueChildren()
                {
                    foreach (Control child in next.Controls)
                    {
                        queue.Enqueue(child);
                    }
                }
            }
        }
Beispiel #2
0
        /// <summary>
        ///   Restores the position of a form from the user settings. Does
        ///   nothing if there is no entry for the form in the settings, or the
        ///   setting would be invisible on the current display configuration.
        /// </summary>
        protected virtual void RestorePosition()
        {
            if (!_needsPositionRestore)
            {
                return;
            }

            if (WindowState == FormWindowState.Minimized)
            {
                // TODO: do we still need to assert when restored it is shown on the correct monitor?
                return;
            }

            var position = _windowPositionManager.LoadPosition(this);

            if (position == null)
            {
                return;
            }

            _needsPositionRestore = false;

            var workingArea = _getScreensWorkingArea();

            if (!workingArea.Any(screen => screen.IntersectsWith(position.Rect)))
            {
                if (position.State == FormWindowState.Maximized)
                {
                    WindowState = FormWindowState.Maximized;
                }

                return;
            }

            SuspendLayout();

            var windowCentred = StartPosition == FormStartPosition.CenterParent;

            StartPosition = FormStartPosition.Manual;

            if (FormBorderStyle == FormBorderStyle.Sizable ||
                FormBorderStyle == FormBorderStyle.SizableToolWindow)
            {
                Size = DpiUtil.Scale(position.Rect.Size, originalDpi: position.DeviceDpi);
            }

            if (Owner == null || !windowCentred)
            {
                var location = DpiUtil.Scale(position.Rect.Location, originalDpi: position.DeviceDpi);

                if (WindowPositionManager.FindWindowScreen(location, workingArea) is Rectangle rect)
                {
                    location.Y = rect.Y;
                }

                DesktopLocation = location;
            }
            else
            {
                // Calculate location for modal form with parent
                Location = new Point(
                    Owner.Left + (Owner.Width / 2) - (Width / 2),
                    Owner.Top + (Owner.Height / 2) - (Height / 2));
            }

            if (WindowState != position.State)
            {
                WindowState = position.State;
            }

            ResumeLayout();
        }
        /// <summary>
        ///   Restores the position of a form from the user settings. Does
        ///   nothing if there is no entry for the form in the settings, or the
        ///   setting would be invisible on the current display configuration.
        /// </summary>
        protected virtual void RestorePosition()
        {
            if (!_needsPositionRestore)
            {
                return;
            }

            if (WindowState == FormWindowState.Minimized)
            {
                return;
            }

            _windowCentred = StartPosition == FormStartPosition.CenterParent;

            var position = LookupWindowPosition(GetType().Name);

            if (position == null)
            {
                return;
            }

            _needsPositionRestore = false;

            if (!Screen.AllScreens.Any(screen => screen.WorkingArea.IntersectsWith(position.Rect)))
            {
                if (position.State == FormWindowState.Maximized)
                {
                    WindowState = FormWindowState.Maximized;
                }

                return;
            }

            SuspendLayout();

            StartPosition = FormStartPosition.Manual;

            if (FormBorderStyle == FormBorderStyle.Sizable ||
                FormBorderStyle == FormBorderStyle.SizableToolWindow)
            {
                Size = DpiUtil.Scale(position.Rect.Size, originalDpi: position.DeviceDpi);
            }

            if (Owner == null || !_windowCentred)
            {
                var location = DpiUtil.Scale(position.Rect.Location, originalDpi: position.DeviceDpi);

                if (FindWindowScreen(location) is Rectangle rect)
                {
                    location.Y = rect.Y;
                }

                DesktopLocation = location;
            }
            else
            {
                // Calculate location for modal form with parent
                Location = new Point(
                    Owner.Left + (Owner.Width / 2) - (Width / 2),
                    Math.Max(0, Owner.Top + (Owner.Height / 2) - (Height / 2)));
            }

            if (WindowState != position.State)
            {
                WindowState = position.State;
            }

            ResumeLayout();

            return;

            Rectangle?FindWindowScreen(Point location)
            {
                var distance = new SortedDictionary <float, Rectangle>();

                foreach (var rect in Screen.AllScreens.Select(screen => screen.WorkingArea))
                {
                    if (rect.Contains(location) && !distance.ContainsKey(0.0f))
                    {
                        return(null); // title in screen
                    }

                    int midPointX = rect.X + (rect.Width / 2);
                    int midPointY = rect.Y + (rect.Height / 2);
                    var d         = (float)Math.Sqrt(((location.X - midPointX) * (location.X - midPointX)) +
                                                     ((location.Y - midPointY) * (location.Y - midPointY)));
                    distance.Add(d, rect);
                }

                return(distance.FirstOrDefault().Value);
            }

            WindowPosition LookupWindowPosition(string name)
            {
                try
                {
                    if (_windowPositionList == null)
                    {
                        _windowPositionList = WindowPositionList.Load();
                    }

                    var pos = _windowPositionList?.Get(name);

                    if (pos != null && !pos.Rect.IsEmpty)
                    {
                        return(pos);
                    }
                }
                catch
                {
                    // TODO: how to restore a corrupted config?
                }

                return(null);
            }
        }
        public FileStatusList()
        {
            InitializeComponent();
            InitialiseFiltering();
            CreateOpenSubmoduleMenuItem();
            lblSplitter.Height = DpiUtil.Scale(1);
            InitializeComplete();
            FilterVisible = false;

            SelectFirstItemOnSetItems = true;

            FileStatusListView.SmallImageList = CreateImageList();
            FileStatusListView.LargeImageList = CreateImageList();

            HandleVisibility_NoFilesLabel_FilterComboBox(filesPresent: true);
            Controls.SetChildIndex(NoFiles, 0);
            NoFiles.Font = new Font(NoFiles.Font, FontStyle.Italic);

            _fullPathResolver = new FullPathResolver(() => Module.WorkingDir);
            _revisionTester   = new GitRevisionTester(_fullPathResolver);

            ImageList CreateImageList()
            {
                const int rowHeight = 18;

                return(new ImageList
                {
                    ImageSize = DpiUtil.Scale(new Size(16, rowHeight)), // Scale ImageSize and images scale automatically
                    Images =
                    {
                        ScaleHeight(Images.FileStatusRemoved),              // 0
                        ScaleHeight(Images.FileStatusAdded),                // 1
                        ScaleHeight(Images.FileStatusModified),             // 2
                        ScaleHeight(Images.FileStatusRenamed),              // 3
                        ScaleHeight(Images.FileStatusCopied),               // 4
                        ScaleHeight(Images.SubmoduleDirty),                 // 5
                        ScaleHeight(Images.SubmoduleRevisionUp),            // 6
                        ScaleHeight(Images.SubmoduleRevisionUpDirty),       // 7
                        ScaleHeight(Images.SubmoduleRevisionDown),          // 8
                        ScaleHeight(Images.SubmoduleRevisionDownDirty),     // 9
                        ScaleHeight(Images.SubmoduleRevisionSemiUp),        // 10
                        ScaleHeight(Images.SubmoduleRevisionSemiUpDirty),   // 11
                        ScaleHeight(Images.SubmoduleRevisionSemiDown),      // 12
                        ScaleHeight(Images.SubmoduleRevisionSemiDownDirty), // 13
                        ScaleHeight(Images.FileStatusUnknown)               // 14
                    }
                });

                Bitmap ScaleHeight(Bitmap input)
                {
                    Debug.Assert(input.Height < rowHeight, "Can only increase row height");
                    var scaled = new Bitmap(input.Width, rowHeight, input.PixelFormat);

                    using (var g = Graphics.FromImage(scaled))
                    {
                        g.DrawImageUnscaled(input, 0, (rowHeight - input.Height) / 2);
                    }

                    return(scaled);
                }
            }
        }
        public static void AdjustForDpiScaling([NotNull] this Control control)
        {
            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            var isDpiScaled = DpiUtil.IsNonStandard;

            var queue = new Queue <Control>();

            queue.Enqueue(control);

            while (queue.Count != 0)
            {
                var next = queue.Dequeue();

                if (next is IComponent component && component.Site?.DesignMode == true)
                {
                    // If we are in design mode, don't scale anything as the designer may
                    // write scaled values back to InitializeComponent.
                    return;
                }

                // NOTE we can't automatically scale TreeView or ListView here as
                // adjustment must be done before images are added to the
                // ImageList otherwise they're all removed.

                switch (next)
                {
                case ButtonBase button:
                {
                    if (isDpiScaled && button.Image != null)
                    {
                        button.Image   = DpiUtil.Scale(button.Image);
                        button.Padding = DpiUtil.Scale(new Padding(4, 0, 4, 0));
                    }

                    break;
                }

                case PictureBox pictureBox:
                {
                    if (isDpiScaled && pictureBox.Image != null)
                    {
                        pictureBox.Image = DpiUtil.Scale(pictureBox.Image);
                    }

                    break;
                }

                case TabControl tabControl:
                {
                    if (!isDpiScaled)
                    {
                        tabControl.Padding = new Point(8, 6);
                    }
                    else if (tabControl.Tag as string != "__DPI_SCALED__")
                    {
                        tabControl.Tag     = "__DPI_SCALED__";
                        tabControl.Padding = DpiUtil.Scale(new Point(8, 6));
                    }

                    EnqueueChildren();
                    break;
                }

                case SplitContainer splitContainer:
                {
                    const int splitterWidth = 8;

                    if (!isDpiScaled)
                    {
                        splitContainer.SplitterWidth = splitterWidth;
                    }
                    else if (splitContainer.Tag as string != "__DPI_SCALED__")
                    {
                        splitContainer.Tag           = "__DPI_SCALED__";
                        splitContainer.SplitterWidth = DpiUtil.Scale(splitterWidth);
                    }

                    splitContainer.BackColor = Color.FromArgb(218, 218, 218);
                    EnqueueChildren();
                    break;
                }

                case TextBoxBase textBox when next.Margin == new Padding(12):
                {
                    // Work around a bug in WinForms where the control's margin gets scaled beyond expectations
                    // see https://github.com/gitextensions/gitextensions/issues/5098
                    textBox.Margin = DpiUtil.Scale(new Padding(3));
                    EnqueueChildren();
                    break;
                }

                case UpDownBase upDown when next.Margin == new Padding(96):
                {
                    // Work around a bug in WinForms where the control's margin gets scaled beyond expectations
                    // see https://github.com/gitextensions/gitextensions/issues/5098
                    upDown.Margin = DpiUtil.Scale(new Padding(3));
                    EnqueueChildren();
                    break;
                }

                default:
                {
                    EnqueueChildren();
                    break;
                }
                }

                void EnqueueChildren()
                {
                    foreach (Control child in next.Controls)
                    {
                        queue.Enqueue(child);
                    }
                }
            }
        }
        public static void AdjustForDpiScaling([NotNull] this Control control)
        {
            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            if (!DpiUtil.IsNonStandard)
            {
                return;
            }

            var queue = new Queue <Control>();

            queue.Enqueue(control);

            while (queue.Count != 0)
            {
                var next = queue.Dequeue();

                // NOTE we can't automatically scale TreeView or ListView here as
                // adjustment must be done before images are added to the
                // ImageList otherwise they're all removed.

                switch (next)
                {
                case ButtonBase button:
                {
                    if (button.Image != null)
                    {
                        button.Image = DpiUtil.Scale(button.Image);
                    }

                    break;
                }

                case PictureBox pictureBox:
                {
                    if (pictureBox.Image != null)
                    {
                        pictureBox.Image = DpiUtil.Scale(pictureBox.Image);
                    }

                    break;
                }

                case TabControl tabControl:
                {
                    tabControl.Padding = DpiUtil.Scale(tabControl.Padding);
                    EnqueueChildren();
                    break;
                }

                default:
                {
                    EnqueueChildren();
                    break;
                }
                }

                void EnqueueChildren()
                {
                    foreach (Control child in next.Controls)
                    {
                        queue.Enqueue(child);
                    }
                }
            }
        }
Beispiel #7
0
 private void UpdateState(bool isManagingRebase)
 {
     Action.Visible     = isManagingRebase;
     FileName.Visible   = !isManagingRebase;
     CommitHash.Visible = isManagingRebase;
     dateDataGridViewTextBoxColumn.Width = isManagingRebase ? DpiUtil.Scale(110) : DpiUtil.Scale(160);
 }
Beispiel #8
0
 public MaskPanel()
 {
     Image     = DpiUtil.Scale(Properties.Resources.loadingpanel);
     SizeMode  = PictureBoxSizeMode.CenterImage;
     BackColor = SystemColors.AppWorkspace;
 }
Beispiel #9
0
        public static void AdjustForDpiScaling(this Control control)
        {
            if (control is null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            var isDpiScaled = DpiUtil.IsNonStandard;

            // If we are in design mode, don't scale anything as the designer may
            // write scaled values back to InitializeComponent.
            if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
            {
                return;
            }

            foreach (var descendant in control.FindDescendants())
            {
                // NOTE we can't automatically scale TreeView or ListView here as
                // adjustment must be done before images are added to the
                // ImageList otherwise they're all removed.
                switch (descendant)
                {
                case ButtonBase button:
                {
                    if (isDpiScaled && button.Image is not null)
                    {
                        button.Image   = DpiUtil.Scale(button.Image);
                        button.Padding = DpiUtil.Scale(new Padding(4, 0, 4, 0));
                    }

                    break;
                }

                case PictureBox pictureBox:
                {
                    if (isDpiScaled && pictureBox.Image is not null)
                    {
                        pictureBox.Image = DpiUtil.Scale(pictureBox.Image);
                    }

                    break;
                }

                case TabControl tabControl:
                {
                    if (!isDpiScaled)
                    {
                        tabControl.Padding = new Point(8, 6);
                    }
                    else if (tabControl.Tag as string != "__DPI_SCALED__")
                    {
                        tabControl.Tag     = "__DPI_SCALED__";
                        tabControl.Padding = DpiUtil.Scale(new Point(8, 6));
                    }

                    break;
                }

                case SplitContainer splitContainer:
                {
                    const int splitterWidth = 8;

                    if (!isDpiScaled)
                    {
                        splitContainer.SplitterWidth = splitterWidth;
                    }
                    else if (splitContainer.Tag as string != "__DPI_SCALED__")
                    {
                        splitContainer.Tag           = "__DPI_SCALED__";
                        splitContainer.SplitterWidth = DpiUtil.Scale(splitterWidth);
                    }

                    splitContainer.BackColor = ColorHelper.GetSplitterColor();
                    break;
                }

                case TextBoxBase textBox when textBox.Margin == new Padding(12):
                {
                    // Work around a bug in WinForms where the control's margin gets scaled beyond expectations
                    // see https://github.com/gitextensions/gitextensions/issues/5098
                    textBox.Margin = DpiUtil.Scale(new Padding(3));
                    break;
                }

                case UpDownBase upDown when upDown.Margin == new Padding(96):
                {
                    // Work around a bug in WinForms where the control's margin gets scaled beyond expectations
                    // see https://github.com/gitextensions/gitextensions/issues/5098
                    upDown.Margin = DpiUtil.Scale(new Padding(3));
                    break;
                }
                }
            }
        }