Skip to content

Commit

Permalink
Merge pull request #180 from noseglid/panel-orientation
Browse files Browse the repository at this point in the history
Panel orientation
  • Loading branch information
noseglid committed Sep 23, 2015
2 parents f5aab75 + 506555a commit 73c07ef
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 30 deletions.
87 changes: 65 additions & 22 deletions lib/build-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

var _ = require('lodash');
var View = require('atom-space-pen-views').View;
var $ = require('atom-space-pen-views').$;
var ansi_up = require('ansi_up');
var cscompatability = require('./cscompatability');
var GoogleAnalytics = require('./google-analytics');
Expand All @@ -21,9 +22,12 @@ module.exports = (function() {
this.buffer = new Buffer(0);
this.links = [];

this._setMonocleIcon();

atom.config.observe('build.panelVisibility', this.visibleFromConfig.bind(this));
atom.config.observe('build.monocleHeight', this.heightFromConfig.bind(this));
atom.config.observe('build.minimizedHeight', this.heightFromConfig.bind(this));
atom.config.observe('build.panelOrientation', this.orientationFromConfig.bind(this));
atom.config.observe('build.monocleHeight', this.sizeFromConfig.bind(this));
atom.config.observe('build.minimizedHeight', this.sizeFromConfig.bind(this));

atom.commands.add('atom-workspace', 'build:toggle-panel', this.toggle.bind(this));
}
Expand All @@ -41,7 +45,7 @@ module.exports = (function() {

BuildView.div({ class: 'output panel-body', outlet: 'output' });

BuildView.div(function() {
BuildView.div({ class: 'status' }, function() {
BuildView.h1({ class: 'title panel-heading', outlet: 'title' }, function () {
BuildView.span({ class: 'build-timer', outlet: 'buildTimer' }, '0.0 s');
BuildView.span({ class: 'title-text', outlet: 'titleText' }, 'Ready');
Expand All @@ -62,9 +66,15 @@ module.exports = (function() {
if (this.panel) {
this.panel.destroy();
}
this.panel = atom.workspace.addBottomPanel({ item: this });
this.height = this.output.offset().top + this.output.height();
this.heightFromConfig();
let addfn = {
Top: atom.workspace.addTopPanel,
Bottom: atom.workspace.addBottomPanel,
Left: atom.workspace.addLeftPanel,
Right: atom.workspace.addRightPanel
};
let orientation = atom.config.get('build.panelOrientation') || 'Bottom';
this.panel = addfn[orientation].call(atom.workspace, { item: this });
this.sizeFromConfig();
};

BuildView.prototype.detach = function(force) {
Expand All @@ -82,12 +92,8 @@ module.exports = (function() {
return !!this.panel;
};

BuildView.prototype.heightFromConfig = function() {
if (this.monocle) {
this.setHeightPercent(atom.config.get('build.monocleHeight'));
} else {
this.setHeightPercent(atom.config.get('build.minimizedHeight'));
}
BuildView.prototype.sizeFromConfig = function() {
this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight'));
};

BuildView.prototype.visibleFromConfig = function(val) {
Expand All @@ -101,6 +107,15 @@ module.exports = (function() {
}
};

BuildView.prototype.orientationFromConfig = function (val) {
let isVisible = this.isVisible();
this.detach(true);
if (isVisible) {
this.attach();
this._setMonocleIcon();
}
};

BuildView.prototype.reset = function() {
clearTimeout(this.titleTimer);
this.buffer = new Buffer(0);
Expand Down Expand Up @@ -137,21 +152,49 @@ module.exports = (function() {
atom.commands.dispatch(atom.views.getView(atom.workspace), 'build:trigger');
};

BuildView.prototype.setHeightPercent = function(percent) {
var newHeight = percent * this.height;
this.output.css('height', newHeight + 'px');
BuildView.prototype.setSizePercent = function(percent) {
let size = 0, cssKey = 'height';
switch (atom.config.get('build.panelOrientation')) {
case 'Top':
case 'Bottom':
size = $('atom-workspace-axis.vertical').height();
cssKey = 'height';
break;

case 'Left':
case 'Right':
size = $('atom-workspace-axis.vertical').width();
if ($('.build').length) {
size += $('.build').get(0).clientWidth;
}
cssKey = 'width';
break;
}
this.output.css('width', 'auto');
this.output.css('height', '100%');
this.output.css(cssKey, percent * size + 'px');
};

BuildView.prototype._setMonocleIcon = function () {
let iconName = () => {
switch (atom.config.get('build.panelOrientation')) {
case 'Top': return this.monocle ? 'icon-chevron-up' : 'icon-chevron-down';
case 'Bottom': return this.monocle ? 'icon-chevron-down' : 'icon-chevron-up';
case 'Right': return this.monocle ? 'icon-chevron-right' : 'icon-chevron-left';
case 'Left': return this.monocle ? 'icon-chevron-left' : 'icon-chevron-right';
}
};

this.monocleButton
.removeClass('icon-chevron-down icon-chevron-up icon-chevron-left icon-chevron-right')
.addClass(iconName());
};

BuildView.prototype.toggleMonocle = function(event, element) {
GoogleAnalytics.sendEvent('view', 'monocle toggled');
if (!this.monocle) {
this.setHeightPercent(atom.config.get('build.monocleHeight'));
this.monocleButton.removeClass('icon-chevron-up').addClass('icon-chevron-down');
} else {
this.setHeightPercent(atom.config.get('build.minimizedHeight'));
this.monocleButton.removeClass('icon-chevron-down').addClass('icon-chevron-up');
}
this.monocle = !this.monocle;
this.setSizePercent(atom.config.get(this.monocle ? 'build.monocleHeight' : 'build.minimizedHeight'));
this._setMonocleIcon();
};

BuildView.prototype.buildStarted = function() {
Expand Down
8 changes: 8 additions & 0 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ module.exports = {
minimum: 0.1,
maximum: 0.9,
order: 7
},
panelOrientation: {
title: 'Panel Orientation',
description: 'Where to attach the build panel',
type: 'string',
default: 'Bottom',
enum: [ 'Bottom', 'Top', 'Left', 'Right' ],
order: 8
}
},

Expand Down
5 changes: 2 additions & 3 deletions spec/build-error-match-spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
'use babel';
'use strict';

var fs = require('fs-extra');
Expand Down Expand Up @@ -349,7 +348,7 @@ describe('Error Match', function() {

waits(100);
runs(function() {
expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135);
expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168);
atom.commands.dispatch(workspaceElement, 'build:error-match');
});

Expand Down Expand Up @@ -382,7 +381,7 @@ describe('Error Match', function() {

waits(100);
runs(function() {
expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(135);
expect(workspaceElement.querySelector('.build .output').scrollTop).toEqual(168);
atom.commands.dispatch(workspaceElement, 'build:error-match-first');
});

Expand Down
88 changes: 87 additions & 1 deletion spec/build-view-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var fs = require('fs-extra');
var temp = require('temp');
var specHelpers = require('./spec-helpers');

describe('Visible', function() {
describe('BuildView', function() {

var directory = null;
var workspaceElement = null;
Expand Down Expand Up @@ -160,4 +160,90 @@ describe('Visible', function() {
});
});
});

describe('when panel orientation is altered', function () {
it('should show the panel at the bottom spot', function () {
expect(workspaceElement.querySelector('.build')).not.toExist();
atom.config.set('build.panelOrientation', 'Bottom');

fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
cmd: 'echo this will fail && exit 1',
}));
atom.commands.dispatch(workspaceElement, 'build:trigger');

waitsFor(function() {
return workspaceElement.querySelector('.build .title') &&
workspaceElement.querySelector('.build .title').classList.contains('error');
});

runs(function() {
var bottomPanels = atom.workspace.getBottomPanels();
expect(bottomPanels.length).toEqual(1);
expect(bottomPanels[0].item.constructor.name).toEqual('BuildView');
});
});

it('should show the panel at the bottom spot', function () {
expect(workspaceElement.querySelector('.build')).not.toExist();
atom.config.set('build.panelOrientation', 'Left');

fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
cmd: 'echo this will fail && exit 1',
}));
atom.commands.dispatch(workspaceElement, 'build:trigger');

waitsFor(function() {
return workspaceElement.querySelector('.build .title') &&
workspaceElement.querySelector('.build .title').classList.contains('error');
});

runs(function() {
var panels = atom.workspace.getLeftPanels();
expect(panels.length).toEqual(1);
expect(panels[0].item.constructor.name).toEqual('BuildView');
});
});

it('should show the panel at the bottom spot', function () {
expect(workspaceElement.querySelector('.build')).not.toExist();
atom.config.set('build.panelOrientation', 'Top');

fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
cmd: 'echo this will fail && exit 1',
}));
atom.commands.dispatch(workspaceElement, 'build:trigger');

waitsFor(function() {
return workspaceElement.querySelector('.build .title') &&
workspaceElement.querySelector('.build .title').classList.contains('error');
});

runs(function() {
var panels = atom.workspace.getTopPanels();
expect(panels.length).toEqual(1);
expect(panels[0].item.constructor.name).toEqual('BuildView');
});
});

it('should show the panel at the bottom spot', function () {
expect(workspaceElement.querySelector('.build')).not.toExist();
atom.config.set('build.panelOrientation', 'Right');

fs.writeFileSync(directory + '.atom-build.json', JSON.stringify({
cmd: 'echo this will fail && exit 1',
}));
atom.commands.dispatch(workspaceElement, 'build:trigger');

waitsFor(function() {
return workspaceElement.querySelector('.build .title') &&
workspaceElement.querySelector('.build .title').classList.contains('error');
});

runs(function() {
var panels = atom.workspace.getRightPanels();
expect(panels.length).toEqual(1);
expect(panels[0].item.constructor.name).toEqual('BuildView');
});
});
});
});
23 changes: 19 additions & 4 deletions styles/build.less
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
@import "ui-variables";
@status-panel-height: 3em;

.build {

height: 100%;

.title {
transition: background-color 0.2s ease-in;
}
Expand Down Expand Up @@ -30,16 +34,27 @@
}

.output {
transition: height 0.5s ease-in-out;
padding: 10px 0 0 10px;
transition: 0.5s ease-in-out;
transition-property: width, height;
padding: 10px 0 @status-panel-height 10px;
min-height: 100px;
overflow-y: auto;
overflow: auto;
word-wrap: break-word;
white-space: pre-wrap;
list-style: none;
font-family: monospace;
}

.status {
position: absolute;
bottom: 0;
height: @status-panel-height;
width: 100%;

h1 {
height: 100%;
}
}

a {
text-decoration: underline;
}
Expand Down

0 comments on commit 73c07ef

Please sign in to comment.