This commit is contained in:
Eugene Pankov 2017-01-18 22:58:04 +01:00
parent f08bf49b62
commit b7745bdd5b
9 changed files with 66 additions and 63 deletions

View File

@ -22,7 +22,7 @@ import { HotkeyInputComponent } from 'components/hotkeyInput'
import { HotkeyDisplayComponent } from 'components/hotkeyDisplay' import { HotkeyDisplayComponent } from 'components/hotkeyDisplay'
import { HotkeyHintComponent } from 'components/hotkeyHint' import { HotkeyHintComponent } from 'components/hotkeyHint'
import { HotkeyInputModalComponent } from 'components/hotkeyInputModal' import { HotkeyInputModalComponent } from 'components/hotkeyInputModal'
import { SettingsModalComponent } from 'components/settingsModal' import { SettingsPaneComponent } from 'components/settingsPane'
import { TerminalComponent } from 'components/terminal' import { TerminalComponent } from 'components/terminal'
@ -48,7 +48,6 @@ import { TerminalComponent } from 'components/terminal'
], ],
entryComponents: [ entryComponents: [
HotkeyInputModalComponent, HotkeyInputModalComponent,
SettingsModalComponent,
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
@ -57,7 +56,7 @@ import { TerminalComponent } from 'components/terminal'
HotkeyHintComponent, HotkeyHintComponent,
HotkeyInputComponent, HotkeyInputComponent,
HotkeyInputModalComponent, HotkeyInputModalComponent,
SettingsModalComponent, SettingsPaneComponent,
TerminalComponent, TerminalComponent,
], ],
bootstrap: [ bootstrap: [

View File

@ -19,6 +19,8 @@
.button-states() { .button-states() {
transition: 0.125s all; transition: 0.125s all;
border: none;
background: transparent;
&:hover:not(.active) { &:hover:not(.active) {
background: rgba(255, 255, 255, .033); background: rgba(255, 255, 255, .033);
@ -43,7 +45,7 @@
-webkit-app-region: drag; -webkit-app-region: drag;
} }
.btn-minimize, .btn-maximize, .btn-close { button {
flex: none; flex: none;
line-height: @titlebar-height - 2px; line-height: @titlebar-height - 2px;
padding: 0 15px; padding: 0 15px;
@ -62,32 +64,36 @@
flex: none; flex: none;
height: @tabs-height; height: @tabs-height;
background: @body-bg; background: @body-bg;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
.btn-settings, .btn-new-tab, .tab { &>button, .tab {
line-height: @tabs-height - 2px; line-height: @tabs-height - 2px;
cursor: pointer; cursor: pointer;
} }
.btn-new-tab, .btn-settings { &>button {
padding: 0 15px; padding: 0 15px;
flex: none; flex: none;
flex-grow: 0; flex-grow: 0;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;
transition: 0.25s all; transition: 0.25s all;
font-size: 12px;
.button-states();
text-transform: uppercase; text-transform: uppercase;
font-weight: bold; font-weight: bold;
color: #888; color: #888;
background: #141c23; background: #141c23;
}
i { &.active-tab-0 .btn-new-tab {
margin-right: 10px; border-bottom-right-radius: @tab-border-radius;
} }
.button-states(); .tab.active + button {
border-bottom-left-radius: @tab-border-radius;
} }
.tab { .tab {
@ -99,6 +105,7 @@
overflow: hidden; overflow: hidden;
min-width: 0; min-width: 0;
background: @body-bg; background: @body-bg;
transition: 0.25s all;
.button-states(); .button-states();
@ -108,6 +115,7 @@
flex: auto; flex: auto;
min-width: 0; min-width: 0;
background: #141c23; background: #141c23;
transition: 0.25s all;
div.index { div.index {
flex: none; flex: none;
@ -162,7 +170,7 @@
//border-bottom: 2px solid transparent; //border-bottom: 2px solid transparent;
transition: 0.25s all; transition: 0.25s all;
&.pre-selected, &:nth-last-child(2) { &.pre-selected, &:nth-last-child(1) {
.content-wrapper { .content-wrapper {
border-bottom-right-radius: @tab-border-radius; border-bottom-right-radius: @tab-border-radius;
} }
@ -195,7 +203,7 @@
display: none; display: none;
flex: auto; flex: auto;
position: relative; position: relative;
padding: 10px 15px; padding: 15px;
&.active { &.active {
display: flex; display: flex;

View File

@ -1,13 +1,15 @@
.titlebar .titlebar
.title((dblclick)='hostApp.maximizeWindow()') Term .title((dblclick)='hostApp.maximizeWindow()') Term
.btn-minimize((click)='hostApp.minimizeWindow()') button.btn-minimize((click)='hostApp.minimizeWindow()')
i.fa.fa-window-minimize i.fa.fa-window-minimize
.btn-maximize((click)='hostApp.maximizeWindow()') button.btn-maximize((click)='hostApp.maximizeWindow()')
i.fa.fa-window-maximize i.fa.fa-window-maximize
.btn-close((click)='hostApp.quit()') button.btn-close((click)='hostApp.quit()')
i.fa.fa-close i.fa.fa-close
.tabs .tabs(class='active-tab-{{tabs.indexOf(activeTab)}}')
button.btn-new-tab((click)='newTab()')
i.fa.fa-plus
.tab( .tab(
*ngFor='let tab of tabs; let idx = index; trackBy: tab?.id', *ngFor='let tab of tabs; let idx = index; trackBy: tab?.id',
(click)='selectTab(tab)', (click)='selectTab(tab)',
@ -20,15 +22,13 @@
div.index {{idx + 1}} div.index {{idx + 1}}
div.name {{tab.name || 'Terminal'}} div.name {{tab.name || 'Terminal'}}
button((click)='closeTab(tab)') × button((click)='closeTab(tab)') ×
.btn-new-tab((click)='newTab()') button.btn-settings((click)='showSettings()')
i.fa.fa-plus
span Tab
.btn-settings((click)='showSettings()')
i.fa.fa-cog i.fa.fa-cog
.tabs-content .tabs-content
.tab(*ngFor='let tab of tabs; trackBy: tab?.id', [class.active]='tab == activeTab') .tab(*ngFor='let tab of tabs; trackBy: tab?.id', [class.active]='tab == activeTab')
terminal([session]='tab.session', '[(title)]'='tab.name') terminal(*ngIf='tab.type == "terminal"', [session]='tab.session', '[(title)]'='tab.name')
settings-pane(*ngIf='tab.type == "settings"')
hotkey-hint hotkey-hint

View File

@ -1,5 +1,4 @@
import { Component, ElementRef, trigger, style, animate, transition, state } from '@angular/core' import { Component, ElementRef, trigger, style, animate, transition, state } from '@angular/core'
import { ModalService } from 'services/modal'
import { ElectronService } from 'services/electron' import { ElectronService } from 'services/electron'
import { HostAppService } from 'services/hostApp' import { HostAppService } from 'services/hostApp'
import { HotkeysService } from 'services/hotkeys' import { HotkeysService } from 'services/hotkeys'
@ -8,19 +7,23 @@ import { QuitterService } from 'services/quitter'
import { ToasterConfig } from 'angular2-toaster' import { ToasterConfig } from 'angular2-toaster'
import { Session, SessionsService } from 'services/sessions' import { Session, SessionsService } from 'services/sessions'
import { SettingsModalComponent } from 'components/settingsModal'
import 'angular2-toaster/lib/toaster.css' import 'angular2-toaster/lib/toaster.css'
import 'global.less' import 'global.less'
const TYPE_TERMINAL = 'terminal'
const TYPE_SETTINGS = 'settings'
class Tab { class Tab {
id: number id: number
name: string name: string
static lastTabID = 0 static lastTabID = 0
constructor (public session: Session) { constructor (public type: string, public session: Session) {
this.id = Tab.lastTabID++ this.id = Tab.lastTabID++
if (type == TYPE_SETTINGS) {
this.name = 'Settings'
}
} }
} }
@ -55,7 +58,6 @@ export class AppComponent {
lastTabIndex = 0 lastTabIndex = 0
constructor( constructor(
private modal: ModalService,
private elementRef: ElementRef, private elementRef: ElementRef,
private sessions: SessionsService, private sessions: SessionsService,
public hostApp: HostAppService, public hostApp: HostAppService,
@ -118,11 +120,11 @@ export class AppComponent {
} }
newTab () { newTab () {
this.addSessionTab(this.sessions.createNewSession({command: 'bash'})) this.addTerminalTab(this.sessions.createNewSession({command: 'bash'}))
} }
addSessionTab (session) { addTerminalTab (session) {
let tab = new Tab(session) let tab = new Tab(TYPE_TERMINAL, session)
this.tabs.push(tab) this.tabs.push(tab)
this.selectTab(tab) this.selectTab(tab)
} }
@ -161,7 +163,9 @@ export class AppComponent {
} }
closeTab (tab) { closeTab (tab) {
tab.session.gracefullyDestroy() if (tab.session) {
tab.session.gracefullyDestroy()
}
let newIndex = Math.max(0, this.tabs.indexOf(tab) - 1) let newIndex = Math.max(0, this.tabs.indexOf(tab) - 1)
this.tabs = this.tabs.filter((x) => x != tab) this.tabs = this.tabs.filter((x) => x != tab)
if (tab == this.activeTab) { if (tab == this.activeTab) {
@ -173,7 +177,7 @@ export class AppComponent {
this.sessions.recoverAll().then((recoveredSessions) => { this.sessions.recoverAll().then((recoveredSessions) => {
if (recoveredSessions.length > 0) { if (recoveredSessions.length > 0) {
recoveredSessions.forEach((session) => { recoveredSessions.forEach((session) => {
this.addSessionTab(session) this.addTerminalTab(session)
}) })
} else { } else {
this.newTab() this.newTab()
@ -185,6 +189,11 @@ export class AppComponent {
} }
showSettings() { showSettings() {
this.modal.open(SettingsModalComponent) let settingsTab = this.tabs.find((x) => x.type == TYPE_SETTINGS)
if (!settingsTab) {
settingsTab = new Tab(TYPE_SETTINGS, null)
this.tabs.push(settingsTab)
}
this.selectTab(settingsTab)
} }
} }

View File

@ -1,20 +0,0 @@
div.modal-body
ngb-tabset(type='tabs nav-justified')
ngb-tab
template(ngbTabTitle)
i.fa.fa-keyboard-o
| Hotkeys
template(ngbTabContent)
.form-group
table.table
tr
th Toggle terminal window
td
hotkey-input('[(model)]'='globalHotkey')
div.modal-footer
div.btn-group.btn-group-justified
a.btn.btn-default((click)='close()')
i.fa.fa-fw.fa-check
br
| Done

View File

@ -0,0 +1,12 @@
ngb-tabset(type='tabs nav-justified')
ngb-tab
template(ngbTabTitle)
i.fa.fa-keyboard-o
| Hotkeys
template(ngbTabContent)
.form-group
table.table
tr
th Toggle terminal window
td
hotkey-input('[(model)]'='globalHotkey')

View File

@ -2,17 +2,15 @@ import { Component } from '@angular/core'
import { ElectronService } from 'services/electron' import { ElectronService } from 'services/electron'
import { HostAppService, PLATFORM_WINDOWS, PLATFORM_LINUX, PLATFORM_MAC } from 'services/hostApp' import { HostAppService, PLATFORM_WINDOWS, PLATFORM_LINUX, PLATFORM_MAC } from 'services/hostApp'
import { ConfigService } from 'services/config' import { ConfigService } from 'services/config'
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'
@Component({ @Component({
selector: 'settings-modal', selector: 'settings-pane',
template: require('./settingsModal.pug'), template: require('./settingsPane.pug'),
styles: [require('./settingsModal.less')], styles: [require('./settingsPane.less')],
}) })
export class SettingsModalComponent { export class SettingsPaneComponent {
constructor( constructor(
private modalInstance: NgbActiveModal,
public config: ConfigService, public config: ConfigService,
hostApp: HostAppService, hostApp: HostAppService,
electron: ElectronService, electron: ElectronService,
@ -35,8 +33,4 @@ export class SettingsModalComponent {
ngOnDestroy() { ngOnDestroy() {
this.config.save() this.config.save()
} }
close() {
this.modalInstance.close()
}
} }

View File

@ -22,6 +22,7 @@ hterm.hterm.VT.ESC['k'] = function(parseState) {
hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory() hterm.hterm.defaultStorage = new hterm.lib.Storage.Memory()
const pmgr = new hterm.hterm.PreferenceManager('default') const pmgr = new hterm.hterm.PreferenceManager('default')
pmgr.set('user-css', ``) pmgr.set('user-css', ``)
pmgr.set('font-size', 12)
pmgr.set('background-color', '#1D272D') pmgr.set('background-color', '#1D272D')
pmgr.set('color-palette-overrides', { pmgr.set('color-palette-overrides', {
0: '#1D272D', 0: '#1D272D',