Skip to content

Commit 0059217

Browse files
committed
Tab styling and navigation shortcuts.
Signed-off-by: ubi de feo <me@ubidefeo.com>
1 parent 5bedc6b commit 0059217

5 files changed

Lines changed: 46 additions & 6 deletions

File tree

backend/menu.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,18 @@ module.exports = function registerMenu(win, state = {}) {
180180
enabled: state.isConnected && state.view === 'editor',
181181
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.CLEAR_TERMINAL)
182182
},
183+
{
184+
label: 'Next Tab',
185+
accelerator: shortcuts.menu.TAB_NEXT,
186+
enabled: state.view === 'editor',
187+
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.TAB_NEXT)
188+
},
189+
{
190+
label: 'Previous Tab',
191+
accelerator: shortcuts.menu.TAB_PREV,
192+
enabled: state.view === 'editor',
193+
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.TAB_PREV)
194+
},
183195
{ type: 'separator' },
184196
{ role: 'resetZoom' },
185197
{ role: 'zoomIn' },

backend/shortcuts.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const shortcuts = {
1717
FILES_VIEW: 'CommandOrControl+Alt+2',
1818
SELECT_FUNCTION: 'CommandOrControl+Alt+A',
1919
SELECT_LINE: 'CommandOrControl+Alt+L',
20+
TAB_NEXT: 'Control+Tab',
21+
TAB_PREV: 'Control+Shift+Tab',
2022
},
2123
menu: {
2224
CLOSE: 'CmdOrCtrl+W',
@@ -34,6 +36,8 @@ const shortcuts = {
3436
FILES_VIEW: 'CmdOrCtrl+Alt+2',
3537
SELECT_FUNCTION: 'CmdOrCtrl+Alt+A',
3638
SELECT_LINE: 'CmdOrCtrl+Alt+L',
39+
TAB_NEXT: 'Ctrl+Tab',
40+
TAB_PREV: 'Ctrl+Shift+Tab',
3741
},
3842
// Shortcuts
3943
}

ui/arduino/main.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ button.small .icon {
240240
background: #ECF1F1;
241241
font-size: 14px;
242242
position: relative;
243+
border-bottom: 1px solid #008184;
243244
}
244245

245246
.tab {
@@ -254,6 +255,9 @@ button.small .icon {
254255
background: #DAE3E3;
255256
overflow: hidden;
256257
transition: all 0.1s;
258+
position: relative;
259+
top: 1px
260+
border-bottom: 1px solid #008184;;
257261
}
258262

259263
.tab:hover {
@@ -262,6 +266,11 @@ button.small .icon {
262266

263267
.tab.active {
264268
background: #FFF;
269+
border-width: 1px 1px 0 1px;
270+
border-color: #008184;;
271+
border-style: solid;
272+
position: relative;
273+
bottom: -1px;
265274
}
266275

267276
.tab .icon {

ui/arduino/store.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1848,6 +1848,14 @@ async function store(state, emitter) {
18481848
if (state.view != 'editor') return
18491849
emitter.emit('change-view', 'file-manager')
18501850
}
1851+
if (key === shortcuts.TAB_NEXT || key === shortcuts.TAB_PREV) {
1852+
if (state.view !== 'editor' || state.openFiles.length < 2) return
1853+
const idx = state.openFiles.findIndex(f => f.id === state.editingFile)
1854+
const next = key === shortcuts.TAB_NEXT
1855+
? (idx + 1) % state.openFiles.length
1856+
: (idx - 1 + state.openFiles.length) % state.openFiles.length
1857+
emitter.emit('select-tab', state.openFiles[next].id)
1858+
}
18511859
// if (key === shortcuts.ESC) {
18521860
// if (state.isConnectionDialogOpen) {
18531861
// emitter.emit('close-connection-dialog')

ui/arduino/views/components/tabs.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ let _emit = null
22
let _containerWidth = 0
33
let _dropdownOpen = false
44
let _resizeObserver = null
5+
let _windowStart = 0
56

67
// Each tab: 140px min-width + 20px padding + 6px gap = 166px slot
78
const TAB_SLOT = 166
@@ -38,14 +39,20 @@ function Tabs(state, emit) {
3839
? calcVisibleCount(_containerWidth, files.length)
3940
: files.length
4041

41-
// Slide window so active tab is always visible
42-
let start = 0
43-
let end = Math.min(visibleCount, files.length)
44-
if (activeIndex >= end) {
45-
end = activeIndex + 1
46-
start = Math.max(0, end - visibleCount)
42+
// Clamp _windowStart so it never leaves trailing empty slots after resize/close
43+
_windowStart = Math.min(_windowStart, Math.max(0, files.length - visibleCount))
44+
_windowStart = Math.max(0, _windowStart)
45+
46+
// Scroll only when active tab falls outside the current window
47+
if (activeIndex < _windowStart) {
48+
_windowStart = activeIndex
49+
} else if (activeIndex >= _windowStart + visibleCount) {
50+
_windowStart = activeIndex - visibleCount + 1
4751
}
4852

53+
const start = _windowStart
54+
const end = Math.min(start + visibleCount, files.length)
55+
4956
const visibleFiles = files.slice(start, end)
5057
const overflowFiles = [...files.slice(0, start), ...files.slice(end)]
5158
const hasOverflow = overflowFiles.length > 0

0 commit comments

Comments
 (0)