@@ -13,12 +13,19 @@ Column {
1313 property int draggedIndex: - 1
1414 property int dropTargetIndex: - 1
1515 property bool suppressShiftAnimation: false
16- readonly property real tabItemSize: 128 + Theme .spacingXS
16+ property int editingIndex: - 1
17+ readonly property real tabItemSize: tabRow .dynamicTabWidth + Theme .spacingXS
1718
1819 signal tabSwitched (int tabIndex)
1920 signal tabClosed (int tabIndex)
2021 signal newTabRequested
2122
23+ function commitRename (index , newTitle ) {
24+ if (index >= 0 )
25+ NotepadStorageService .renameTab (index, newTitle);
26+ editingIndex = - 1 ;
27+ }
28+
2229 function hasUnsavedChangesForTab (tab ) {
2330 if (! tab)
2431 return false ;
@@ -32,11 +39,19 @@ Column {
3239 spacing: Theme .spacingXS
3340
3441 Row {
42+ id: tabRow
3543 width: parent .width
3644 height: 36
3745 spacing: Theme .spacingXS
3846
47+ readonly property real dynamicTabWidth: {
48+ var count = Math .max (1 , NotepadStorageService .tabs .length );
49+ var raw = (tabScroll .width - (count - 1 ) * Theme .spacingXS ) / count;
50+ return Math .max (128 , Math .min (300 , raw));
51+ }
52+
3953 ScrollView {
54+ id: tabScroll
4055 width: parent .width - newTabButton .width - Theme .spacingXS
4156 height: parent .height
4257 clip: true
@@ -57,7 +72,8 @@ Column {
5772
5873 readonly property bool isActive: NotepadStorageService .currentTabIndex === index
5974 readonly property bool isHovered: tabMouseArea .containsMouse && ! closeMouseArea .containsMouse
60- readonly property real tabWidth: 128
75+ readonly property bool editing: root .editingIndex === index
76+ readonly property real tabWidth: tabRow .dynamicTabWidth
6177 property bool longPressing: false
6278 property bool dragging: false
6379 property point dragStartPos: Qt .point (0 , 0 )
@@ -138,6 +154,7 @@ Column {
138154
139155 StyledText {
140156 id: tabText
157+ visible: ! delegateItem .editing
141158 width: parent .width - (tabCloseButton .visible ? tabCloseButton .width + Theme .spacingXS : 0 )
142159 text: {
143160 var prefix = " " ;
@@ -155,13 +172,54 @@ Column {
155172 anchors .verticalCenter : parent .verticalCenter
156173 }
157174
175+ TextInput {
176+ id: renameField
177+ visible: delegateItem .editing
178+ enabled: delegateItem .editing
179+ width: parent .width
180+ anchors .verticalCenter : parent .verticalCenter
181+ font .pixelSize : Theme .fontSizeSmall
182+ font .weight : Font .Medium
183+ color: Theme .primary
184+ selectionColor: Theme .primary
185+ selectedTextColor: Theme .background
186+ selectByMouse: true
187+ clip: true
188+
189+ onEditingFinished: root .commitRename (index, text)
190+ Keys .onEscapePressed : event => {
191+ text = modelData .title || " Untitled" ;
192+ root .editingIndex = - 1 ;
193+ event .accepted = true ;
194+ }
195+
196+ // A tab switch re-focuses the editor via Qt.callLater; the
197+ // timer fires afterwards so the field keeps focus + selection.
198+ Timer {
199+ id: renameFocusTimer
200+ interval: 20
201+ repeat: false
202+ onTriggered: {
203+ renameField .forceActiveFocus ();
204+ renameField .selectAll ();
205+ }
206+ }
207+
208+ onVisibleChanged: {
209+ if (! visible)
210+ return ;
211+ text = modelData .title || " Untitled" ;
212+ renameFocusTimer .restart ();
213+ }
214+ }
215+
158216 Rectangle {
159217 id: tabCloseButton
160218 width: 20
161219 height: 20
162220 radius: Theme .cornerRadius
163221 color: closeMouseArea .containsMouse ? Theme .surfaceTextHover : Theme .withAlpha (Theme .surfaceTextHover , 0 )
164- visible: NotepadStorageService .tabs .length > 1
222+ visible: NotepadStorageService .tabs .length > 1 && ! delegateItem . editing
165223 anchors .verticalCenter : parent .verticalCenter
166224
167225 DankIcon {
@@ -195,11 +253,24 @@ Column {
195253 MouseArea {
196254 id: tabMouseArea
197255 anchors .fill : parent
256+ enabled: ! delegateItem .editing
198257 hoverEnabled: true
199258 preventStealing: dragging || longPressing
200259 cursorShape: dragging || longPressing ? Qt .ClosedHandCursor : Qt .PointingHandCursor
201260 acceptedButtons: Qt .LeftButton
202261
262+ onDoubleClicked: {
263+ root .tabSwitched (index);
264+ root .editingIndex = index;
265+ }
266+
267+ onExited: tabTooltip .hide ()
268+
269+ onContainsMouseChanged: {
270+ if (containsMouse && tabText .truncated )
271+ tabTooltip .show (modelData .title || " Untitled" , delegateItem, 0 , 0 , " bottom" );
272+ }
273+
203274 onPressed : mouse => {
204275 if (mouse .button === Qt .LeftButton && NotepadStorageService .tabs .length > 1 ) {
205276 delegateItem .dragStartPos = Qt .point (mouse .x , mouse .y );
@@ -279,4 +350,8 @@ Column {
279350 onClicked: root .newTabRequested ()
280351 }
281352 }
353+
354+ DankTooltipV2 {
355+ id: tabTooltip
356+ }
282357}
0 commit comments