Skip to content

Commit

Permalink
Merge pull request #47 from learningmedia/context-menu
Browse files Browse the repository at this point in the history
Context menu
  • Loading branch information
ahelmberger committed Mar 30, 2018
2 parents cf90998 + 481ffa7 commit 3378df8
Show file tree
Hide file tree
Showing 17 changed files with 189 additions and 8 deletions.
4 changes: 3 additions & 1 deletion app/client/app.js
Expand Up @@ -24,6 +24,8 @@ const updateNotification = require('./components/update-notification');
const partOperations = require('./bindings/part-operations');
const Messenger = require('../shared/messenger');
const splashScreen = require('./components/splash-screen');
const flyoutMenu = require('./components/flyout-menu.js')
const flyoutMenuItem = require('./components/flyout-menu-item.js')

const logger = new Logger(__filename);

Expand All @@ -49,7 +51,7 @@ window.ko = ko;
[fileDrop, partOperations].forEach(binding => binding.register());

// Register all components:
[work, part, inspector, soundPlayer, annotation, checkbox, updateNotification, splashScreen].forEach(component => component.register());
[work, part, inspector, soundPlayer, annotation, checkbox, updateNotification, splashScreen, flyoutMenu, flyoutMenuItem].forEach(component => component.register());

// Add specific functions to the app vm:
appViewModel.onFileDropped = files => {
Expand Down
9 changes: 7 additions & 2 deletions app/client/components/annotation.html
@@ -1,3 +1,8 @@
<div class="Annotation" data-bind="foreach: { data: tuples, as: 'tuple' }">
<textarea class="Annotation-value" rows="1" data-bind="style: { flex: tuple.length }, event: { blur: $component.onBlur }, value: tuple.text"></textarea>
<div class="Annotation">
<div class="Annotation-values" data-bind="foreach: { data: tuples, as: 'tuple' }">
<textarea class="Annotation-value" rows="1" data-bind="style: { flex: tuple.length }, event: { blur: $component.onBlur }, value: tuple.text"></textarea>
</div>
<av-flyout-menu class="Annotation-flyOutMenu">
<av-flyout-menu-item params="label: 'Löschen', onClick: onDeleteClick"></av-flyout-menu-item>
</av-flyout-menu>
</div>
6 changes: 6 additions & 0 deletions app/client/components/annotation.js
Expand Up @@ -4,6 +4,7 @@ const ko = require('knockout');
const template = fs.readFileSync(`${__dirname}/annotation.html`, 'utf8');

function viewModel(params) {
const work = params.work;
const subscriptions = [];

const valuesPerPart = params.parts()
Expand Down Expand Up @@ -43,9 +44,14 @@ function viewModel(params) {
params.annotation.values(params.parts().map(part => valuesPerPart[part.id()]()));
}

function deleteAnnotation() {
work.annotations.remove(params.annotation);
}

return {
tuples: tuples,
onBlur: (vm, event) => event.target.scrollTop = 0,
onDeleteClick: () => deleteAnnotation(),
dispose: () => subscriptions.forEach(sub => sub.dispose())
};
}
Expand Down
14 changes: 12 additions & 2 deletions app/client/components/annotation.less
Expand Up @@ -4,16 +4,26 @@
@annotation-border-color: @default-text-container-border-color;
@annotation-background-color: @default-text-container-background-color;
@annotation-background-color-alternate: @default-text-container-background-color-alternate;
@annotation-flyout-menu: @default-flyout-menu-indent;

av-annotation {
display: block;
}

.Annotation {
display: flex;
width: 100%;
overflow: auto;
position: relative;
}

.Annotation-flyOutMenu {
position: absolute;
top: @annotation-flyout-menu;
}

.Annotation-values {
border: 1px solid @annotation-border-color;
overflow: auto;
display: flex;
}

.Annotation-value {
Expand Down
1 change: 1 addition & 0 deletions app/client/components/flyout-menu-item.html
@@ -0,0 +1 @@
<a class="FlyoutMenuItem" data-bind="text: label, click: onClick"></a>
22 changes: 22 additions & 0 deletions app/client/components/flyout-menu-item.js
@@ -0,0 +1,22 @@
const fs = require('fs');
const ko = require('knockout');

const template = fs.readFileSync(`${__dirname}/flyout-menu-item.html`, 'utf8');

function viewModel(params) {
const label = params.label;
const onClick = params.onClick;
return {
label,
onClick
};
}

function register() {
ko.components.register('av-flyout-menu-item', {
viewModel: viewModel,
template: template
});
}

module.exports = { register };
10 changes: 10 additions & 0 deletions app/client/components/flyout-menu-item.less
@@ -0,0 +1,10 @@
@import '../styles/variables';

.FlyoutMenuItem {
display: block;
padding: 2px 10px;

&:hover {
background-color: @default-flyout-menu-background-color-hover;
}
}
6 changes: 6 additions & 0 deletions app/client/components/flyout-menu.html
@@ -0,0 +1,6 @@
<div class="FlyoutMenu">
<div class="FlyoutMenu-trigger" data-bind="click: toggleFlyout"></div>
<div class="FlyoutMenu-flyoutContainer">
<div class="FlyoutMenu-flyout" data-bind="template: { nodes: $componentTemplateNodes, data: $parent }, visible: isFlyoutVisible"></div>
</div>
</div>
20 changes: 20 additions & 0 deletions app/client/components/flyout-menu.js
@@ -0,0 +1,20 @@
const fs = require('fs');
const ko = require('knockout');

const template = fs.readFileSync(`${__dirname}/flyout-menu.html`, 'utf8');

function viewModel(params) {
const vm = {};
vm.isFlyoutVisible = ko.observable(false);
vm.toggleFlyout = () => vm.isFlyoutVisible(!vm.isFlyoutVisible());
return vm;
}

function register() {
ko.components.register('av-flyout-menu', {
viewModel: viewModel,
template: template
});
}

module.exports = { register };
34 changes: 34 additions & 0 deletions app/client/components/flyout-menu.less
@@ -0,0 +1,34 @@
@import '../styles/mixins';
@import '../styles/variables';

@arrow-size: 5px;
@background-color: @default-background-color-light;
@border-color: @default-flyout-menu-border-color;

av-flyout-menu {
display: block;
}

.FlyoutMenu {
width: 20px;
}

.FlyoutMenu-trigger {
.m-icon-wrench;
.m-darken-on-hover;
cursor: pointer;
}

.FlyoutMenu-flyoutContainer {
position: relative;
height: 0px;
}

.FlyoutMenu-flyout {
.m-bubble(@arrow-size, @background-color, @border-color);
position: absolute;
z-index: 1000;
width: 300px;
box-shadow: 2px 2px 5px 0px @default-flyout-menu-shadow-color;
padding: 5px 2px;
}
6 changes: 4 additions & 2 deletions app/client/components/sound-player.html
Expand Up @@ -10,9 +10,11 @@
<div class="SoundPlayer-progressGrid" data-bind="foreach: { data: parts, as: 'part' }">
<span class="SoundPlayer-progressGridPart" data-bind="style: { flex: part.length }"></span>
</div>
<progress class="SoundPlayer-progress" data-bind="attr: { max: sound().length, value: sound().position }, click: onProgressClick">
<progress class="SoundPlayer-progress" data-bind="attr: { max: sound().length, value: sound().position }, click: onProgressClick"></progress>
</div>
</progress>
<av-flyout-menu class="SoundPlayer-flyOutMenu">
<av-flyout-menu-item params="label: 'Löschen', onClick: onDeleteClick"></av-flyout-menu-item>
</av-flyout-menu>
<div class="SoundPlayer-controller">
<button data-bind="click: onStartClick">Start</button>
<button data-bind="click: onStopClick">Stopp</button>
Expand Down
5 changes: 5 additions & 0 deletions app/client/components/sound-player.js
Expand Up @@ -73,12 +73,17 @@ function viewModel(params) {
}
});
},
onDeleteClick: () => deleteSound(params.work, params.sound),
dispose: function () {
sound().stop();
}
};
}

function deleteSound(work, sound){
work.sounds.remove(sound);
}

function copyFileSync(srcFile, destFile) {
const BUF_LENGTH = 64 * 1024;
const buff = new Buffer(BUF_LENGTH);
Expand Down
7 changes: 7 additions & 0 deletions app/client/components/sound-player.less
Expand Up @@ -6,12 +6,14 @@
@sound-player-background-color: @default-control-background-color;
@sound-player-progress-bar-color: @default-control-highlight-overlay-color;
@sound-player-shadow: @default-glossy-shadow;
@sound-player-flyout-menu: @default-flyout-menu-indent;

av-sound-player {
display: block;
}

.SoundPlayer {
position: relative;
}

.SoundPlayer-progressContainer {
Expand Down Expand Up @@ -60,6 +62,11 @@ av-sound-player {
}
}

.SoundPlayer-flyOutMenu {
position: absolute;
top: @sound-player-flyout-menu;
}

.SoundPlayer-controller {
margin-top: 10px;
text-align: center;
Expand Down
2 changes: 1 addition & 1 deletion app/client/components/work.html
Expand Up @@ -11,7 +11,7 @@
<av-part params="app: $parent.app, work: $parent.work, part: part" data-bind="style: { flex: part.length }"></av-part>
</div>
<!-- ko foreach: { data: annotations, as: 'annotation' } -->
<av-annotation class="Work-annotation" params="annotation: annotation, parts: $parent.parts"></av-annotation>
<av-annotation class="Work-annotation" params="annotation: annotation, parts: $parent.parts, work: $parent.work"></av-annotation>
<!-- /ko -->
<!-- ko foreach: { data: sounds, as: 'sound' } -->
<av-sound-player class="Work-soundPlayer" params="sound: sound, work: $parent.work"></av-sound-player>
Expand Down
2 changes: 2 additions & 0 deletions app/client/main.less
Expand Up @@ -18,3 +18,5 @@
@import './components/checkbox';
@import './components/update-notification';
@import './components/splash-screen';
@import './components/flyout-menu';
@import './components/flyout-menu-item';
41 changes: 41 additions & 0 deletions app/client/styles/mixins.less
Expand Up @@ -106,3 +106,44 @@
color: @color-light-blue-600;
}
}

.m-icon-wrench {
.m-icon;
&:before {
content: @fa-var-wrench;
font-size: 20px;
color: @color-light-blue-600;
}
}

.m-bubble(@arrow-size, @background-color, @border-color) {
position: relative;
background: @background-color;
border: 1px solid @border-color;

&:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 @arrow-size @arrow-size;
border-color: @background-color transparent;
display: block;
width: 0;
z-index: 1;
top: -@arrow-size;
left: @arrow-size;
}

&:before {
content: '';
position: absolute;
border-style: solid;
border-width: 0 @arrow-size @arrow-size;
border-color: @border-color transparent;
display: block;
width: 0;
z-index: 0;
top: -(@arrow-size + 1px);
left: @arrow-size;
}
}
8 changes: 8 additions & 0 deletions app/client/styles/variables.less
Expand Up @@ -8,6 +8,7 @@
@default-background-color: @color-grey-100;
@default-background-color-light: @color-grey-50;
@default-control-border-color: @color-grey-400;
@default-control-border-color-dark: @color-grey-600;
@default-control-background-color: lighten(@default-control-border-color, 10%);
@default-control-highlight-overlay-color: fade(@color-blue-400, 33%);

Expand All @@ -32,3 +33,10 @@
@default-notification-background-color: @color-green-400;
@default-notification-color: @color-black-darker;
@default-notification-opacity: 0.8;

@default-flyout-menu-border-color: @default-control-border-color-dark;
@default-flyout-menu-shadow-color: @color-black-dark;
@default-flyout-menu-background-color: @default-background-color-light;
@default-flyout-menu-background-color-hover: darken(@default-background-color-light, 10);

@default-flyout-menu-indent: -6px;

0 comments on commit 3378df8

Please sign in to comment.