Skip to content

Commit d930db5

Browse files
committed
Merge titlebar and tabbar into a single row
Set TABBAR_H to 0 and increase TITLEBAR_H to 36. Tabs are now rendered inline in the titlebar after the dropdown button, with tab click handling moved into the titlebar region. The separate render_tabbar() is now a no-op. This puts the dropdown icon, tabs, and window controls all on one line, eliminating the second row. https://claude.ai/code/session_013uWpT9xBhNcN2PtRU4XotZ
1 parent f296ee3 commit d930db5

File tree

3 files changed

+73
-77
lines changed

3 files changed

+73
-77
lines changed

prose_code.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ typedef struct {
111111
#define CLR_SEARCH_HL (g_theme.search_hl)
112112

113113
/* ── Layout constants ── */
114-
#define TITLEBAR_H 30
115-
#define TABBAR_H 38
114+
#define TITLEBAR_H 36
115+
#define TABBAR_H 0
116116
#define MENUBAR_H 0
117117
#define STATUSBAR_H 30
118118
#define GUTTER_PAD 16

render.c

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ void render_titlebar(HDC hdc) {
2929

3030
/* Dropdown trigger button (small down arrow) */
3131
int btn_size = DPI(22);
32-
int btn_x = DPI(8);
32+
int btn_x = DPI(6);
3333
int btn_y = (th - btn_size) / 2;
3434

3535
COLORREF btn_bg;
@@ -48,14 +48,37 @@ void render_titlebar(HDC hdc) {
4848
SetTextColor(hdc, icon_clr);
4949
DrawTextW(hdc, L"\x25BE", 1, &br, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
5050

51-
/* Document title */
52-
int title_x = btn_x + btn_size + DPI(10);
53-
SelectObject(hdc, g_editor.font_title);
54-
Document *doc = current_doc();
55-
if (doc) {
56-
wchar_t title[256];
57-
swprintf(title, 256, L"%ls%ls", doc->title, doc->modified ? L" \x2022" : L"");
58-
draw_text(hdc, title_x, (th - DPI(16)) / 2, title, (int)wcslen(title), CLR_SUBTEXT);
51+
/* Tabs (inline, right after dropdown button) */
52+
int tx = btn_x + btn_size + DPI(8);
53+
int right_limit = g_editor.client_w - DPI(46) * 3 - DPI(8);
54+
SelectObject(hdc, g_editor.font_ui_small);
55+
56+
for (int i = 0; i < g_editor.tab_count; i++) {
57+
Document *doc = g_editor.tabs[i];
58+
wchar_t label[128];
59+
swprintf(label, 128, L"%ls%ls", doc->title, doc->modified ? L" \x2022" : L"");
60+
int tw = (int)wcslen(label) * DPI(8) + DPI(TAB_PAD) * 2;
61+
if (tw < DPI(TAB_MIN_W)) tw = DPI(TAB_MIN_W);
62+
if (tw > DPI(TAB_MAX_W)) tw = DPI(TAB_MAX_W);
63+
64+
if (tx + tw > right_limit) break;
65+
66+
if (i == g_editor.active_tab) {
67+
fill_rounded_rect(hdc, tx, DPI(5), tw, th - DPI(5), DPI(10), CLR_TAB_ACTIVE);
68+
fill_rounded_rect(hdc, tx + DPI(12), th - DPI(3), tw - DPI(24), DPI(2), DPI(1), CLR_ACCENT);
69+
draw_text(hdc, tx + DPI(TAB_PAD), (th - DPI(12)) / 2, label, (int)wcslen(label), CLR_TEXT);
70+
} else {
71+
draw_text(hdc, tx + DPI(TAB_PAD), (th - DPI(12)) / 2, label, (int)wcslen(label), CLR_OVERLAY0);
72+
}
73+
74+
draw_text(hdc, tx + tw - DPI(20), (th - DPI(12)) / 2, L"\x00D7", 1, CLR_OVERLAY0);
75+
76+
tx += tw + DPI(4);
77+
}
78+
79+
/* New tab (+) button */
80+
if (tx + DPI(30) <= right_limit) {
81+
draw_text(hdc, tx + DPI(8), (th - DPI(12)) / 2, L"+", 1, CLR_OVERLAY0);
5982
}
6083

6184
/* Window control buttons */
@@ -86,38 +109,8 @@ void render_titlebar(HDC hdc) {
86109
}
87110

88111
void render_tabbar(HDC hdc) {
89-
int y = DPI(TITLEBAR_H + MENUBAR_H);
90-
int tbh = DPI(TABBAR_H);
91-
fill_rect(hdc, 0, y, g_editor.client_w, tbh, CLR_BG_DARK);
92-
93-
SelectObject(hdc, g_editor.font_ui_small);
94-
SetBkMode(hdc, TRANSPARENT);
95-
96-
int x = DPI(8);
97-
for (int i = 0; i < g_editor.tab_count; i++) {
98-
Document *doc = g_editor.tabs[i];
99-
wchar_t label[128];
100-
swprintf(label, 128, L"%ls%ls", doc->title, doc->modified ? L" \x2022" : L"");
101-
int tw = (int)wcslen(label) * DPI(8) + DPI(TAB_PAD) * 2;
102-
if (tw < DPI(TAB_MIN_W)) tw = DPI(TAB_MIN_W);
103-
if (tw > DPI(TAB_MAX_W)) tw = DPI(TAB_MAX_W);
104-
105-
if (i == g_editor.active_tab) {
106-
fill_rounded_rect(hdc, x, y + DPI(5), tw, tbh - DPI(5), DPI(10), CLR_TAB_ACTIVE);
107-
fill_rounded_rect(hdc, x + DPI(12), y + tbh - DPI(3), tw - DPI(24), DPI(2), DPI(1), CLR_ACCENT);
108-
draw_text(hdc, x + DPI(TAB_PAD), y + (tbh - DPI(12)) / 2, label, (int)wcslen(label), CLR_TEXT);
109-
} else {
110-
draw_text(hdc, x + DPI(TAB_PAD), y + (tbh - DPI(12)) / 2, label, (int)wcslen(label), CLR_OVERLAY0);
111-
}
112-
113-
draw_text(hdc, x + tw - DPI(20), y + (tbh - DPI(12)) / 2, L"\x00D7", 1, CLR_OVERLAY0);
114-
115-
x += tw + DPI(4);
116-
}
117-
118-
draw_text(hdc, x + DPI(8), y + (tbh - DPI(12)) / 2, L"+", 1, CLR_OVERLAY0);
119-
120-
fill_rect(hdc, 0, y + tbh - 1, g_editor.client_w, 1, CLR_SURFACE0);
112+
/* Tabs are now rendered inline in the titlebar */
113+
(void)hdc;
121114
}
122115

123116
void render_statusbar(HDC hdc) {

wndproc.c

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
618618

619619
/* Check dropdown trigger button click */
620620
int btn_size = DPI(22);
621-
int btn_x = DPI(8);
621+
int btn_x = DPI(6);
622622
int btn_y = (DPI(TITLEBAR_H) - btn_size) / 2;
623623

624624
if (mx >= btn_x && mx < btn_x + btn_size &&
@@ -633,6 +633,39 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
633633
return 0;
634634
}
635635

636+
/* Tab clicks (inline in titlebar) */
637+
{
638+
int tx = btn_x + btn_size + DPI(8);
639+
int right_limit = g_editor.client_w - DPI(46) * 3 - DPI(8);
640+
for (int i = 0; i < g_editor.tab_count; i++) {
641+
wchar_t label[128];
642+
swprintf(label, 128, L"%ls%ls", g_editor.tabs[i]->title, g_editor.tabs[i]->modified ? L" \x2022" : L"");
643+
int tw = (int)wcslen(label) * DPI(8) + DPI(TAB_PAD) * 2;
644+
if (tw < DPI(TAB_MIN_W)) tw = DPI(TAB_MIN_W);
645+
if (tw > DPI(TAB_MAX_W)) tw = DPI(TAB_MAX_W);
646+
647+
if (tx + tw > right_limit) break;
648+
649+
if (mx >= tx && mx < tx + tw) {
650+
if (mx >= tx + tw - DPI(24)) {
651+
close_tab(i);
652+
} else {
653+
g_editor.active_tab = i;
654+
}
655+
InvalidateRect(hwnd, NULL, FALSE);
656+
return 0;
657+
}
658+
tx += tw + DPI(4);
659+
}
660+
/* New tab button */
661+
if (tx + DPI(30) <= right_limit &&
662+
mx >= tx + DPI(4) && mx < tx + DPI(30)) {
663+
new_tab();
664+
InvalidateRect(hwnd, NULL, FALSE);
665+
return 0;
666+
}
667+
}
668+
636669
/* Drag to move (anywhere else in titlebar) */
637670
g_editor.titlebar_dragging = 1;
638671
g_editor.drag_start.x = mx;
@@ -641,8 +674,8 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
641674
return 0;
642675
}
643676

644-
/* Combined dropdown click — MUST be checked before tab bar since
645-
* the dropdown overlaps the tab bar's y-range */
677+
/* Combined dropdown click — MUST be checked before editor area since
678+
* the dropdown overlaps the editor's y-range */
646679
if (g_editor.menu_open >= 0) {
647680
int item_h = DPI(26);
648681
int sep_h = DPI(9);
@@ -687,36 +720,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
687720
/* Fall through to handle the click on whatever was underneath */
688721
}
689722

690-
/* Tab bar */
691-
if (my >= DPI(TITLEBAR_H + MENUBAR_H) && my < DPI(TITLEBAR_H + MENUBAR_H + TABBAR_H)) {
692-
int tx = DPI(8);
693-
for (int i = 0; i < g_editor.tab_count; i++) {
694-
wchar_t label[128];
695-
swprintf(label, 128, L"%ls%ls", g_editor.tabs[i]->title, g_editor.tabs[i]->modified ? L" \x2022" : L"");
696-
int tw = (int)wcslen(label) * DPI(8) + DPI(TAB_PAD) * 2;
697-
if (tw < DPI(TAB_MIN_W)) tw = DPI(TAB_MIN_W);
698-
if (tw > DPI(TAB_MAX_W)) tw = DPI(TAB_MAX_W);
699-
700-
if (mx >= tx && mx < tx + tw) {
701-
/* Check close button */
702-
if (mx >= tx + tw - DPI(24)) {
703-
close_tab(i);
704-
} else {
705-
g_editor.active_tab = i;
706-
}
707-
InvalidateRect(hwnd, NULL, FALSE);
708-
return 0;
709-
}
710-
tx += tw + DPI(4);
711-
}
712-
/* New tab button */
713-
if (mx >= tx + DPI(4) && mx < tx + DPI(30)) {
714-
new_tab();
715-
InvalidateRect(hwnd, NULL, FALSE);
716-
}
717-
return 0;
718-
}
719-
720723
/* Search bar close button */
721724
if (g_editor.search.active) {
722725
int bar_h = g_editor.search.replace_active ? DPI(72) : DPI(40);
@@ -863,7 +866,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
863866
g_editor.dropdown_hover = 0;
864867
if (my < DPI(TITLEBAR_H)) {
865868
int btn_size = DPI(22);
866-
int btn_x = DPI(8);
869+
int btn_x = DPI(6);
867870
int btn_y = (DPI(TITLEBAR_H) - btn_size) / 2;
868871
if (mx >= btn_x && mx < btn_x + btn_size &&
869872
my >= btn_y && my < btn_y + btn_size) {

0 commit comments

Comments
 (0)