Skip to content

Commit 8b3ffb7

Browse files
committed
Allow resizing the main window smaller
1 parent 39f2167 commit 8b3ffb7

File tree

1 file changed

+89
-5
lines changed

1 file changed

+89
-5
lines changed

src/J.App/MainForm.cs

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Data;
22
using System.Diagnostics;
3+
using System.Globalization;
34
using System.Text.Json;
45
using System.Web;
56
using J.Core;
@@ -13,6 +14,9 @@ namespace J.App;
1314

1415
public sealed partial class MainForm : Form
1516
{
17+
public const int SEARCH_TEXT_SMALL_WIDTH = 125;
18+
public const int SEARCH_TEXT_BIG_WIDTH = 200;
19+
1620
private readonly IServiceProvider _serviceProvider;
1721
private readonly LibraryProviderAdapter _libraryProvider;
1822
private readonly Client _client;
@@ -59,7 +63,8 @@ public sealed partial class MainForm : Form
5963
_browserTabButton,
6064
_importTabButton,
6165
_tagsTabButton;
62-
private readonly ToolStripSeparator _rightmostSeparator;
66+
private readonly ToolStripSeparator _rightmostSeparator,
67+
_browserNavigationSeparator;
6368
private readonly MyToolStripTextBox _searchText;
6469
private readonly MyWebView2 _browser;
6570
private readonly System.Windows.Forms.Timer _searchDebounceTimer;
@@ -153,7 +158,7 @@ ProcessTempDir processTempDir
153158
_filterClearButton.Click += FilterClearButton_Click;
154159
}
155160

156-
_toolStrip.Items.Add(_searchText = ui.NewToolStripTextBox(200));
161+
_toolStrip.Items.Add(_searchText = ui.NewToolStripTextBox(SEARCH_TEXT_BIG_WIDTH));
157162
{
158163
_searchText.Margin += ui.RightSpacing;
159164
_searchText.Alignment = ToolStripItemAlignment.Right;
@@ -339,7 +344,7 @@ ProcessTempDir processTempDir
339344
};
340345
}
341346

342-
_toolStrip.Items.Add(ui.NewToolStripSeparator());
347+
_toolStrip.Items.Add(_browserNavigationSeparator = ui.NewToolStripSeparator());
343348

344349
_toolStrip.Items.Add(_browserTabButton = ui.NewToolStripTabButton("Loading..."));
345350
{
@@ -441,7 +446,7 @@ ProcessTempDir processTempDir
441446

442447
Text = "Jackpot Media Library";
443448
Size = ui.GetSize(1600, 900);
444-
MinimumSize = ui.GetSize(1200, 400);
449+
MinimumSize = ui.GetSize(900, 400);
445450
CenterToScreen();
446451
FormBorderStyle = FormBorderStyle.None;
447452
Icon = ui.GetIconResource("App.ico");
@@ -596,13 +601,76 @@ private void Browser_NavigationCompleted(object? sender, CoreWebView2NavigationC
596601
if (title.Length > 100)
597602
title = title[..100] + "...";
598603

599-
_browserTabButton.Text = title?.Replace("&", "&&") ?? "";
604+
_browserTabButton.Text = TruncateTitleText(title?.Replace("&", "&&") ?? "", _ui.GetLength(150));
600605
_browseBackButton.Enabled = _browser.CanGoBack;
601606
_browseForwardButton.Enabled = _browser.CanGoForward;
602607
}
603608
catch { }
604609
}
605610

611+
private string TruncateTitleText(string text, int maxPixelWidth)
612+
{
613+
if (string.IsNullOrEmpty(text))
614+
return text;
615+
616+
var font = _browserTabButton.Font;
617+
618+
// Using the Control's context for DPI-aware measurements
619+
using var graphics = CreateGraphics();
620+
621+
// Check if the full text already fits
622+
var fullSize = TextRenderer.MeasureText(
623+
graphics,
624+
text,
625+
font,
626+
new Size(maxPixelWidth, 0),
627+
TextFormatFlags.SingleLine | TextFormatFlags.NoPrefix
628+
);
629+
630+
if (fullSize.Width <= maxPixelWidth)
631+
return text;
632+
633+
// Create text enumerator for proper grapheme cluster handling
634+
var enumerator = StringInfo.GetTextElementEnumerator(text);
635+
List<string> elements = new(text.Length);
636+
while (enumerator.MoveNext())
637+
{
638+
elements.Add(enumerator.GetTextElement());
639+
}
640+
641+
// Binary search for the longest fitting prefix
642+
int left = 0;
643+
int right = elements.Count;
644+
645+
while (left < right)
646+
{
647+
int mid = (left + right + 1) / 2;
648+
string candidate = string.Concat(elements.Take(mid)) + "...";
649+
var size = TextRenderer.MeasureText(
650+
graphics,
651+
candidate,
652+
font,
653+
new Size(maxPixelWidth, 0),
654+
TextFormatFlags.SingleLine | TextFormatFlags.NoPrefix
655+
);
656+
657+
if (size.Width <= maxPixelWidth)
658+
{
659+
left = mid;
660+
}
661+
else
662+
{
663+
right = mid - 1;
664+
}
665+
}
666+
667+
// If we can't fit even one grapheme cluster plus ellipsis, return just ellipsis
668+
if (left == 0)
669+
return "...";
670+
671+
return string.Concat(elements.Take(left)) + "...";
672+
}
673+
606674
private async Task GoHomeAsync()
607675
{
608676
await _client.InhibitScrollRestoreAsync().ConfigureAwait(true);
@@ -1108,6 +1176,22 @@ protected override void OnResize(EventArgs e)
11081176
ApplyFullscreenPreference();
11091177
_lastWindowState = WindowState;
11101178
}
1179+
1180+
var size1 = Width >= _ui.GetLength(1100);
1181+
var size2 = Width >= _ui.GetLength(1300);
1182+
1183+
_viewButton.DisplayStyle = size1 ? ToolStripItemDisplayStyle.ImageAndText : ToolStripItemDisplayStyle.Text;
1184+
_sortButton.DisplayStyle = size1 ? ToolStripItemDisplayStyle.ImageAndText : ToolStripItemDisplayStyle.Text;
1185+
_filterButton.DisplayStyle = size1
1186+
? ToolStripItemDisplayStyle.ImageAndText
1187+
: ToolStripItemDisplayStyle.Text;
1188+
_browserNavigationSeparator.Visible = size1;
1189+
_searchText.Width = _ui.GetLength(size1 ? SEARCH_TEXT_BIG_WIDTH : SEARCH_TEXT_SMALL_WIDTH);
1190+
1191+
_browseBackButton.Visible = size2;
1192+
_browseForwardButton.Visible = size2;
1193+
_refreshButton.Visible = size2;
1194+
_homeButton.Visible = size2;
11111195
}
11121196
catch { }
11131197
}

0 commit comments

Comments
 (0)