private async Task UpdateGravatarAsync() { await this.SwitchToMainThreadAsync(); // resize our control (I'm not using AutoSize for a reason) var size = new Size(AppSettings.AuthorImageSize, AppSettings.AuthorImageSize); DpiUtil.Scale(ref size); Size = _gravatarImg.Size = size; if (!AppSettings.ShowAuthorGravatar || string.IsNullOrEmpty(Email)) { RefreshImage(Resources.User); return; } var image = await _gravatarService.GetAvatarAsync(Email, Math.Max(size.Width, size.Height), AppSettings.GravatarDefaultImageType); RefreshImage(image); }
public void RestoreFromSettings(ISettingsSource settings) { Splitter.BeginInit(); Splitter.SuspendLayout(); int prevDpi = settings.GetInt(DpiSettingsKey) ?? DpiUtil.DpiX; int prevSize = settings.GetInt(SizeSettingsKey) ?? 0; int prevDistance = settings.GetInt(DistanceSettingsKey) ?? 0; if (prevSize > 0 && prevDistance > 0) { if (SplitterSize == prevSize && Dpi == prevDpi) { SetSplitterDistance(prevDistance); } else { switch (Splitter.FixedPanel) { case FixedPanel.None: SetSplitterDistance((float)SplitterSize * prevDistance / prevSize); break; case FixedPanel.Panel1: SetSplitterDistance(DpiUtil.Scale(prevDistance, prevDpi)); break; case FixedPanel.Panel2: int panel2PrevSize = DpiUtil.Scale(prevSize, prevDpi) - DpiUtil.Scale(prevDistance, prevDpi); SetSplitterDistance(SplitterSize - panel2PrevSize); break; } } } Splitter.Panel1Collapsed = settings.GetBool(Panel1CollapsedSettingsKey, defaultValue: false); Splitter.ResumeLayout(); Splitter.EndInit(); }
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 = Color.Transparent; 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; } } } }
/// <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(); }
public MaskPanel() { Image = DpiUtil.Scale(Properties.Resources.loadingpanel); SizeMode = PictureBoxSizeMode.CenterImage; BackColor = SystemColors.AppWorkspace; }
public FileStatusList() { InitializeComponent(); InitialiseFiltering(); CreateOpenSubmoduleMenuItem(); lblSplitter.Height = DpiUtil.Scale(1); InitializeComplete(); FilterVisible = false; SelectFirstItemOnSetItems = true; FileStatusListView.SmallImageList = CreateImageList(); FileStatusListView.LargeImageList = CreateImageList(); FileStatusListView.AllowCollapseGroups = true; 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 void RestoreFromSettings(ISettingsSource settings) { _splitter.BeginInit(); _splitter.SuspendLayout(); int prevDpi = settings.GetInt(DpiSettingsKey) ?? DpiUtil.DpiX; int prevSize = settings.GetInt(SizeSettingsKey) ?? 0; int prevDistance = settings.GetInt(DistanceSettingsKey) ?? 0; if (prevSize > 0 && prevDistance > 0) { var fixedPanel = _splitter.FixedPanel; var splitterWidth = _splitter.SplitterWidth; if (SplitterSize == prevSize && _dpi == prevDpi) { SetSplitterDistance(fixedPanel == FixedPanel.Panel2 ? prevDistance + splitterWidth : prevDistance); } else { switch (fixedPanel) { case FixedPanel.None: // At this point, the property "SplitterSize" has its original value from design time, // i.e. the actual size after opening the window is unknown yet. The calculation below // determines the resulting splitter distance by the ratio of both sides of the splitter. SetSplitterDistance((float)SplitterSize * prevDistance / prevSize); break; case FixedPanel.Panel1: SetSplitterDistance(DpiUtil.Scale(prevDistance, prevDpi)); break; case FixedPanel.Panel2: int panel2PrevSize = DpiUtil.Scale(prevSize, prevDpi) - DpiUtil.Scale(prevDistance, prevDpi); const int paddingOffset = 2; // Refer to FormCommit.ctor+WorkaroundPaddingIncreaseBug SetSplitterDistance(SplitterSize - panel2PrevSize - paddingOffset + splitterWidth); break; } } } _splitter.Panel1Collapsed = settings.GetBool(Panel1CollapsedSettingsKey, defaultValue: false); _splitter.ResumeLayout(); _splitter.EndInit(); }
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); } } } }
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); } } } }
/// <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 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); } } } }
private void UpdateState(bool isManagingRebase) { Action.Visible = isManagingRebase; FileName.Visible = !isManagingRebase; CommitHash.Visible = isManagingRebase; dateDataGridViewTextBoxColumn.Width = isManagingRebase ? DpiUtil.Scale(110) : DpiUtil.Scale(160); }