Skip to content

Commit

Permalink
Merge pull request #295 from aminya/refractor_items
Browse files Browse the repository at this point in the history
Refractor methods, items, etc
  • Loading branch information
suda committed Apr 29, 2020
2 parents fa817a8 + 3ed376b commit 1251183
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 70 deletions.
202 changes: 135 additions & 67 deletions lib/items/tool-bar-button-view.js
Original file line number Diff line number Diff line change
@@ -1,89 +1,155 @@
const {CompositeDisposable} = require('atom');
const { ToolBarItem } = require('./tool-bar-item');

/**
* A button class with many options
*
* @property {HTMLElement} element
* @property {number} priority
* @property {string} group
*
* @property {ButtonOptions} options
* @property {boolean} enabled
* @property {CompositeDisposable} subscriptions
*/
class ToolBarButtonView extends ToolBarItem {
/**
*
* @param {ButtonOptions} options
* @param {string} group
*/
constructor (options, group) {
// first calling the super (ToolBarItem) constructor
super({
element: document.createElement('button'),
priority: options.priority
}, group);

this.subscriptions = new CompositeDisposable();
this.options = options;
this.enabled = true;

if (options.tooltip) {
const callback = this.options.callback;
// default classes
this.classNames = ['btn', 'btn-default', 'tool-bar-btn'];

let tooltip = {};
if (typeof options.tooltip === 'string') {
tooltip = {
title: options.tooltip
};
} else {
tooltip = options.tooltip;
}
if (this.priority < 0) {
this.putAtEnd();
}

if (!tooltip.hasOwnProperty('placement')) {
tooltip.placement = getTooltipPlacement;
}
if (options.icon) {
this.addIcon();
}

if (!tooltip.hasOwnProperty('keyBindingCommand')) {
tooltip.keyBindingCommand = typeof callback === 'string' ? callback : null;
}
if (options.text) {
this.addText();
}

if (options.tooltip) {
this.subscriptions = new CompositeDisposable();
this.subscriptions.add(
atom.tooltips.add(this.element, tooltip)
this.addTooltip(this.options.tooltip, this.options.callback)
);
}

const classNames = ['btn', 'btn-default', 'tool-bar-btn'];
if (this.priority < 0) {
classNames.push('tool-bar-item-align-end');
if (options.color) {
this.addColor();
}
if (options.icon) {
if (options.iconset) {
if (options.iconset.startsWith('fa')) {
classNames.push(options.iconset, `fa-${options.icon}`);
} else {
classNames.push(options.iconset, `${options.iconset}-${options.icon}`);
}
} else {
classNames.push(`icon-${options.icon}`);
}
if (options.background) {
this.addBackgroundColor();
}

if (options.text) {
if (options.html) {
this.element.innerHTML = options.text;
this.addClasses();
this.addOnMouseDown();
this.addOnClick();
}

destroy () {
if (this.subscriptions) {
this.subscriptions.dispose();
this.subscriptions = null;
}
this.element.removeEventListener('mousedown', this._onMouseDown);
this.element.removeEventListener('click', this._onClick);
super.destroy(); // call super.destroy() in the end
}

/** Put the button at the end of the toolbar using 'tool-bar-item-align-end' class. */
putAtEnd () {
this.classNames.push('tool-bar-item-align-end');
}

/** Add an icon for the button using built-in icons. */
addIcon () {
if (this.options.iconset) {
if (this.options.iconset.startsWith('fa')) {
this.classNames.push(this.options.iconset, `fa-${this.options.icon}`);
} else {
this.element.textContent = options.text;
this.classNames.push(this.options.iconset, `${this.options.iconset}-${this.options.icon}`);
}
} else {
this.classNames.push(`icon-${this.options.icon}`);
}
}

if (options.color) {
this.element.style.color = options.color;
/** Adds a text/html to the button */
addText () {
if (this.options.html) {
this.element.innerHTML = this.options.text;
} else {
this.element.textContent = this.options.text;
}
if (options.background) {
this.element.style.background = options.background;
}

/**
* adds a Tooltip for your item.
* @param {ButtonOptions.tooltip} tooltipOptions
* @param {ButtonOptions.callback | null} callback
* @returns {Disposable} a disposable tooltip
*/
addTooltip (tooltipOptions, callback = null) {
let tooltip;
if (typeof tooltipOptions === 'string') {
tooltip = {
title: tooltipOptions
};
} else {
tooltip = tooltipOptions;
}

if (options.class) {
if (Array.isArray(options.class)) {
this.element.classList.add(...options.class);
} else {
this.element.classList.add(options.class);
}
if (!tooltip.hasOwnProperty('placement')) {
tooltip.placement = getTooltipPlacement();
}

if (!tooltip.hasOwnProperty('keyBindingCommand') &&
typeof callback === 'string'
) {
tooltip.keyBindingCommand = callback;
}

this.element.classList.add(...classNames);
return atom.tooltips.add(this.element, tooltip);
}

this._onMouseDown = this._onMouseDown.bind(this);
this._onClick = this._onClick.bind(this);
/** Add color to the button */
addColor () {
this.element.style.color = this.options.color;
}

this.element.addEventListener('mousedown', this._onMouseDown);
this.element.addEventListener('click', this._onClick);
/** Add background color to the button */
addBackgroundColor () {
this.element.style.background = this.options.background;
}

/** Add all the classes (custom and others) to the button */
addClasses () {
// add custom classes to the button
if (this.options.class) {
if (Array.isArray(this.options.class)) {
this.classNames.push(...this.options.class);
} else {
this.element.classList.add(this.options.class);
}
}
// add other classes
this.element.classList.add(...this.classNames);
}

setEnabled (enabled) {
Expand All @@ -107,21 +173,21 @@ class ToolBarButtonView extends ToolBarItem {
return this.element.classList.contains('selected');
}

destroy () {
if (this.subscriptions) {
this.subscriptions.dispose();
this.subscriptions = null;
}
this.element.removeEventListener('mousedown', this._onMouseDown);
this.element.removeEventListener('click', this._onClick);
super.destroy(); // call super.destroy() in the end
addOnMouseDown () {
this._onMouseDown = this._onMouseDown.bind(this);
this.element.addEventListener('mousedown', this._onMouseDown);
}

_onMouseDown (e) {
// Avoid taking focus so we can dispatch Atom commands with the correct target.
e.preventDefault();
}

addOnClick () {
this._onClick = this._onClick.bind(this);
this.element.addEventListener('click', this._onClick);
}

_onClick (e) {
if (this.element && !this.element.classList.contains('disabled')) {
this.executeCallback(e);
Expand Down Expand Up @@ -156,15 +222,6 @@ class ToolBarButtonView extends ToolBarItem {
}
}
}
};

function getTooltipPlacement () {
const toolbarPosition = atom.config.get('tool-bar.position');
return toolbarPosition === 'Top' ? 'bottom'
: toolbarPosition === 'Right' ? 'left'
: toolbarPosition === 'Bottom' ? 'top'
: toolbarPosition === 'Left' ? 'right'
: null;
}

function getCallbackModifier (callback, {altKey, ctrlKey, shiftKey}) {
Expand All @@ -190,4 +247,15 @@ function getCallbackModifier (callback, {altKey, ctrlKey, shiftKey}) {
return callback[modifier] || callback[''];
}

/** get the tooltip placement based on the toolbar position */
function getTooltipPlacement () {
const toolbarPosition = atom.config.get('tool-bar.position');

return toolbarPosition === 'Top' ? 'bottom'
: toolbarPosition === 'Right' ? 'left'
: toolbarPosition === 'Bottom' ? 'top'
: toolbarPosition === 'Left' ? 'right'
: null;
}

module.exports.ToolBarButtonView = ToolBarButtonView;
7 changes: 7 additions & 0 deletions lib/items/tool-bar-item.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
/**
* A minimal class used to manage custom HTML elements in Toolbar.
* This is supposed to be Super for other classes.
* @property {HTMLElement} element
* @property {number} priority
* @property {string} group
*/
class ToolBarItem {
/**
* @param {ItemOptions} options
* @param {string} group
*/
constructor (options, group) {
this.element = options.element;
this.priority = options.priority;
Expand Down
37 changes: 35 additions & 2 deletions lib/tool-bar-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,61 @@ const { ToolBarItem } = require('./items/tool-bar-item');
const { ToolBarButtonView } = require('./items/tool-bar-button-view');
const { ToolBarSpacerView } = require('./items/tool-bar-spacer-view');

module.exports = class ToolBarManager {
/**
*
* @property {string} group
* @property {ToolBarView} toolBarView
* @property {TouchBarManager} touchBarManager
*/
class ToolBarManager {
/**
*
* @param {string} group
* @param {ToolBarView} toolBarView
* @param {TouchBarManager} touchBarManager
*/
constructor (group, toolBarView, touchBarManager) {
this.group = group;
this.toolBarView = toolBarView;
this.touchBarManager = touchBarManager;
}

/** Adds a custom HTML Element to Toolbar. options: {element, priority} */
/**
* Adds a custom HTML Element to Toolbar. options: {element, priority}
* @param {ItemOptions} options
*/
addItem (options) {
const item = new ToolBarItem(options, this.group);
this.toolBarView.addItem(item);
// this.touchBarManager.addItem(item); // TODO
return item;
}

/**
* Adds a button. The input to this function is a `ButtonOptions` object
* @param {ButtonOptions} options
*/
addButton (options) {
const button = new ToolBarButtonView(options, this.group);
this.toolBarView.addItem(button);
this.touchBarManager.addButton(button);
return button;
}

/**
* Adds a spacer. Optionally, you can pass a `SpacerOptions` object
* @param options
* @return {ToolBarSpacerView}
*/
addSpacer (options) {
const spacer = new ToolBarSpacerView(options, this.group);
this.toolBarView.addItem(spacer);
return spacer;
}

/**
* Use the method removeItems to remove the buttons added by your package. This is particular useful in your package deactivate method, but can be used at any time.
*/
removeItems () {
if (this.toolBarView.items) {
this.toolBarView.items
Expand All @@ -39,7 +66,13 @@ module.exports = class ToolBarManager {
}
}

/**
* The onDidDestroy method takes a function that will be called when the tool-bar package is destroyed. This is useful if your package needs to do cleanup when the tool-bar is deactivated but your package continues running.
* @param {() => void} callback
*/
onDidDestroy (callback) {
this.toolBarView.emitter.on('did-destroy', callback);
}
};

module.exports.ToolBarManager = ToolBarManager;
2 changes: 1 addition & 1 deletion lib/tool-bar.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const ToolBarManager = require('./tool-bar-manager');
const { ToolBarManager } = require('./tool-bar-manager');
const ToolBarView = require('./tool-bar-view');
const TouchBarManager = require('./touch-bar-manager');

Expand Down

0 comments on commit 1251183

Please sign in to comment.