Skip to content

Commit

Permalink
Merge pull request #159 from milikhin/harbour-tabs
Browse files Browse the repository at this point in the history
[harbour-seabass] add support for multiple tabs
  • Loading branch information
milikhin authored Jan 4, 2023
2 parents 3357403 + 9537275 commit 565f802
Show file tree
Hide file tree
Showing 28 changed files with 19,710 additions and 5,648 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
node-version: [12.x]
node-version: [18.x]
python-version: [3.8]

steps:
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ editor/coverage
generic/py-backend/.coverage
generic/py-backend/coverage.xml

harbour-seabass/qml/html/
harbour-seabass/qml/html/dist
harbour-seabass/qml/generic/
harbour-seabass/qml/py-backend/
harbour-seabass/qml/py-libs/
Expand Down
1 change: 1 addition & 0 deletions editor/__tests__/app/model.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ describe('SeabassAppModel', () => {
hasChanges: false,
hasUndo: false,
hasRedo: false,
filePath: options.filePath,
isReadOnly: options.isReadOnly
})
})
Expand Down
3 changes: 2 additions & 1 deletion editor/src/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class SeabassApp {
*/
_onOpenFile (evt: CustomEvent<FileActionOptions>): void {
this._tabs.show(evt.detail.filePath)
this._model.forwardEvent(evt.detail.filePath, evt)
}

/**
Expand All @@ -120,7 +121,7 @@ class SeabassApp {
* @param evt viewportChange event
*/
_onViewportChange (evt: CustomEvent<ViewportOptions>): void {
this._model.setViewportOptions(evt.detail)
this._model.setViewportOptions(evt.detail, this._tabs.currentTab?.id)
}

/**
Expand Down
12 changes: 10 additions & 2 deletions editor/src/app/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,22 @@ export default class SeabassAppModel extends EventTarget {
this._editors.set(filePath, editor)

this.dispatchEvent(new CustomEvent('loadFile', { detail: options }))
this.dispatchEvent(new CustomEvent('stateChange', { detail: editor.getUiState() }))
this.dispatchEvent(new CustomEvent('stateChange', {
detail: {
...editor.getUiState(),
filePath
}
}))
}

setViewportOptions (options: ViewportOptions): void {
setViewportOptions (options: ViewportOptions, editorId?: string): void {
this._viewport = {
verticalHtmlOffset: options.verticalHtmlOffset ?? 0
}
this.dispatchEvent(new CustomEvent('viewportChange', { detail: this._viewport }))
if (editorId !== undefined) {
this._editors.get(editorId)?.resize()
}
}

/**
Expand Down
33 changes: 20 additions & 13 deletions editor/src/editor/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,26 @@ export default class Editor extends EventTarget {
}
}

/** Called when editor becomes visible */
openFile (): void {
this._onChange()
}

/** Handles viewport resizing */
resize = (): void => {
this._editor.dispatch({
effects: EditorView.scrollIntoView(this._editor.state.selection.ranges[0])
})
}

async _initLanguageSupport (filePath: string): Promise<void> {
const effects = await this._setup.setupLanguageSupport(filePath)
this._editor.dispatch({ effects })
}

_initDomEventHandlers (): void {
this._editorElem.addEventListener('keypress', evt => {
/* `Enter` and `Backspace` are handled twice on SfOS, disable redundant keypress handler */
if (evt.keyCode === 8 || evt.keyCode === 13) {
evt.preventDefault()
}
}, true)
window.addEventListener('resize', this._onResize)
this._editorElem.addEventListener('keypress', this._onKeyPress, true)
window.addEventListener('resize', this.resize)
}

_onChange (): void {
Expand All @@ -236,15 +243,15 @@ export default class Editor extends EventTarget {
}))
}

_onResize = (): void => {
if (this._isOskVisible) {
this._editor.dispatch({
effects: EditorView.scrollIntoView(this._editor.state.selection.ranges[0])
})
_onKeyPress = (evt: KeyboardEvent): void => {
/* `Enter` and `Backspace` are handled twice on SfOS, disable redundant keypress handler */
if (evt.keyCode === 8 || evt.keyCode === 13) {
evt.preventDefault()
}
}

_removeDomEventHandlers (): void {
window.removeEventListener('resize', this._onResize)
this._editorElem.removeEventListener('keypress', this._onKeyPress, true)
window.removeEventListener('resize', this.resize)
}
}
18 changes: 0 additions & 18 deletions editor/src/editor/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export default class EditorSetup {
keymap.of([indentWithTab, ...historyKeymap]),
this._getDefaultLangExtension(options),
this._getDocChangeHandlerExtension(options),
this._getDomEventHandlerExtension(options),
this._getReadOnlyExtension(options),
this._getThemeExtension(options),
this._getLineWrappingExtension(options),
Expand Down Expand Up @@ -106,23 +105,6 @@ export default class EditorSetup {
})
}

_getDomEventHandlerExtension (options: ExtensionsOptions): Extension {
return EditorView.domEventHandlers({
scroll: evt => {
if (evt.target === null || !('classList' in evt.target)) {
return
}

const target = evt.target as HTMLElement
if (!target.classList.contains('cm-scroller')) {
return
}

options.onChange()
}
})
}

_getIndentationString (editorConfig: SeabassEditorConfig): string {
switch (editorConfig.indentStyle) {
case 'tab':
Expand Down
2 changes: 1 addition & 1 deletion generic/qml/EditorState.qml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import QtQuick 2.0
import '../generic/utils.js' as QmlJs
import './utils.js' as QmlJs

QtObject {
// State
Expand Down
33 changes: 32 additions & 1 deletion generic/qml/TabsModel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import "./utils.js" as QmlJs

// Represents opened tabs
ListModel {
property int currentIndex: -1
property var currentTab: currentIndex === -1 ? undefined : get(currentIndex)
signal tabAdded(var tab, var options)
signal tabClosed(string filePath)

Expand All @@ -38,6 +40,11 @@ ListModel {
}
}

function getTab(id) {
const tabIndex = getIndex(id)
return get(tabIndex)
}

function openTerminal(tabId, title, subTitle) {
return open({
id: tabId,
Expand All @@ -50,6 +57,7 @@ ListModel {
function open(options) {
var existingTabIndex = getIndex(options.id)
if (existingTabIndex !== undefined) {
currentIndex = existingTabIndex
return existingTabIndex
}

Expand All @@ -62,21 +70,30 @@ ListModel {

filePath: options.filePath,
isBusy: false,
hasChanges: false
hasChanges: false,
lastOpened: options.doNotActivate ? undefined : Date.now()
}
append(currentTab)
tabAdded(currentTab, {
createIfNotExists: !options.isRestored,
doNotActivate: options.doNotActivate
})
_updateTabNames()

if (!options.doNotActivate) {
currentIndex = count - 1
}
}

function close(filePath) {
var index = getIndex(filePath)
remove(index, 1)
tabClosed(filePath)
_updateTabNames()

if (index === currentIndex) {
_updateCurrentIndex()
}
}

function patch(filePath, attributes) {
Expand Down Expand Up @@ -155,6 +172,20 @@ ListModel {
return nameGroups
}

function _updateCurrentIndex() {
currentIndex = -1

const files = listFiles();
if (files.length === 0) {
return
}

const currentTab = files.sort(function (a, b) {
return a.lastOpened - b.lastOpened
})[0];
currentIndex = getIndex(currentTab.id)
}

/**
* Updates unique tab titles to make them unique across opened files
* to prevent tabs visual naming collisions.
Expand Down
13 changes: 13 additions & 0 deletions harbour-seabass/harbour-seabass.pro
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,20 @@ TARGET = harbour-seabass

CONFIG += sailfishapp_qml

copyQml.commands = $(COPY_DIR) $$PWD/../generic/qml/* $$PWD/qml/generic
copyPyCode.commands = $(COPY_DIR) $$PWD/../generic/py-backend $$PWD/qml
copyPyLibs1.commands = $(COPY_DIR) $$PWD/../generic/py-libs/inotify_simple $$PWD/qml/py-backend && rm $$PWD/qml/py-backend/inotify_simple/.git
copyPyLibs2.commands = $(COPY_DIR) $$PWD/../generic/py-libs/editorconfig-core-py/editorconfig $$PWD/qml/py-backend

first.depends = $(first) copyQml copyPyCode copyPyLibs1 copyPyLibs2
copyPyLibs1.depends = copyPyCode
copyPyLibs2.depends = copyPyCode
export(first.depends)
QMAKE_EXTRA_TARGETS += first copyQml copyPyCode copyPyLibs1 copyPyLibs2

DISTFILES += qml/harbour-seabass.qml \
qml/components/Configuration.qml \
qml/components/Tabs.qml \
qml/components/TabsButton.qml \
qml/components/Toolbar.qml \
qml/generic/EditorApi.qml \
Expand Down
26 changes: 26 additions & 0 deletions harbour-seabass/qml/components/Configuration.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import QtQuick 2.0
import Nemo.Configuration 1.0

Item {
property alias isToolbarVisible: configToolbarVisible.value
property alias fontSize: configFontSize.value
property alias useWrapMode: configUseWrapMode.value

ConfigurationValue {
id: configToolbarVisible
key: "/apps/harbour-seabass/settings/is_toolbar_visible"
defaultValue: true
}

ConfigurationValue {
id: configFontSize
key: "/apps/harbour-seabass/settings/font_size"
defaultValue: 12
}

ConfigurationValue {
id: configUseWrapMode
key: "/apps/harbour-seabass/settings/soft_wrap_enabled"
defaultValue: true
}
}
62 changes: 62 additions & 0 deletions harbour-seabass/qml/components/Tabs.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import QtQuick 2.2
import Sailfish.Silica 1.0

Drawer {
id: root
property int currentIndex: -1
property string title: 'Tabs'
property alias model: list.model

signal newTabRequested()
signal selected(string id)
signal closed(string id)
signal closedAll()

background: SilicaListView {
id: list
anchors.fill: parent
header: PageHeader {
title: root.title
}

PullDownMenu {
MenuItem {
text: qsTr("Open file...")
onClicked: {
root.newTabRequested()
}
}
MenuItem {
text: qsTr("Close all")
onClicked: {
root.closedAll()
}
}
}
VerticalScrollDecorator {}

delegate: ListItem {
id: listItem
onClicked: {
root.selected(model.id)
}
menu: Component {
ContextMenu {
MenuItem {
text: "Close"
onClicked: {
root.closed(model.id)
}
}
}
}

Label {
x: Theme.horizontalPageMargin
text: model.hasChanges ? ('* ' + model.uniqueTitle) : model.uniqueTitle
anchors.verticalCenter: parent.verticalCenter
highlighted: listItem.highlighted
}
}
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,22 @@

<body>
<div id="welcome">
<p>
v0.11 introduces Settings page.
It is possible to change font size and text wrapping.
</p>
<p>
Please let me know if you have any issues:
<a target="_blank" href="https://github.com/milikhin/seabass2" target="_blank">Seabass on Github</a>.
</p>
<h3>
Features:
</h3>
<ul>
<li>syntax highlighting for over 100 programming/markup languages</li>
<li>multiple tabs</li>
<li>navigation buttons</li>
<li>light and dark themes</li>
<li>reading indentation preferences from .editorconfig files</a></li>
</ul>
<h3>
New:
</h3>
<ul>
<li>v1.0 adds support for multiple simultaneously opened files</li>
</ul>
</div>
<div id="root"></div>

Expand All @@ -42,7 +50,7 @@
apiTransport: 'Sailfish webView',
}
</script>
<script src="./bundle.js"></script>
<script src="./dist/bundle.js"></script>
</body>

</html>
Loading

0 comments on commit 565f802

Please sign in to comment.