blob: acbb92e7978695025f59ed8d48c169ee4318937f [file] [log] [blame]
Deepanjan Roy9d95a252018-08-09 10:10:19 -04001// Copyright (C) 2018 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import * as m from 'mithril';
16
17import {moveTrack} from '../common/actions';
18import {TrackState} from '../common/state';
19
20import {globals} from './globals';
21import {drawGridLines} from './gridline_helper';
22import {quietDispatch} from './mithril_helpers';
23import {Panel} from './panel';
24import {Track} from './track';
25import {trackRegistry} from './track_registry';
26
Hector Dearman3ae7eb72018-08-14 17:51:14 +010027// TODO(hjd): We should remove the constant where possible.
28// If any uses can't be removed we should read this constant from CSS.
Primiano Tuccidc3dbcb2018-08-10 00:34:33 +010029export const TRACK_SHELL_WIDTH = 300;
Deepanjan Roy9d95a252018-08-09 10:10:19 -040030
31const TrackShell = {
32 view({attrs}) {
33 return m(
34 '.track-shell',
Deepanjan Roy9d95a252018-08-09 10:10:19 -040035 m('h1', attrs.trackState.name),
Hector Dearman3ae7eb72018-08-14 17:51:14 +010036 m(TrackMoveButton, {
37 direction: 'up',
38 trackId: attrs.trackState.id,
39 }),
40 m(TrackMoveButton, {
41 direction: 'down',
42 trackId: attrs.trackState.id,
43 }));
Deepanjan Roy9d95a252018-08-09 10:10:19 -040044 },
45} as m.Component<{trackState: TrackState}>;
46
47const TrackContent = {
48 view({attrs}) {
49 return m('.track-content', {
Deepanjan Roy9d95a252018-08-09 10:10:19 -040050 onmousemove: (e: MouseEvent) => {
Deepanjan Roy9d95a252018-08-09 10:10:19 -040051 attrs.track.onMouseMove({x: e.layerX, y: e.layerY});
Primiano Tuccif30cd9c2018-08-13 01:53:26 +020052 globals.rafScheduler.scheduleOneRedraw();
Deepanjan Roy9d95a252018-08-09 10:10:19 -040053 },
54 onmouseout: () => {
55 attrs.track.onMouseOut();
Primiano Tuccif30cd9c2018-08-13 01:53:26 +020056 globals.rafScheduler.scheduleOneRedraw();
Deepanjan Roy9d95a252018-08-09 10:10:19 -040057 },
58 }, );
59 }
60} as m.Component<{track: Track}>;
61
62const TrackComponent = {
63 view({attrs}) {
64 return m('.track', [
65 m(TrackShell, {trackState: attrs.trackState}),
66 m(TrackContent, {track: attrs.track})
Hector Dearman3ae7eb72018-08-14 17:51:14 +010067 ]);
Deepanjan Roy9d95a252018-08-09 10:10:19 -040068 }
69} as m.Component<{trackState: TrackState, track: Track}>;
70
71const TrackMoveButton = {
72 view({attrs}) {
73 return m(
74 'i.material-icons.track-move-icons',
75 {
76 onclick: quietDispatch(moveTrack(attrs.trackId, attrs.direction)),
Deepanjan Roy9d95a252018-08-09 10:10:19 -040077 },
78 attrs.direction === 'up' ? 'arrow_upward_alt' : 'arrow_downward_alt');
79 }
80} as m.Component<{
81 direction: 'up' | 'down',
82 trackId: string,
Deepanjan Roy9d95a252018-08-09 10:10:19 -040083},
84 {}>;
85
Deepanjan Royabd79aa2018-08-28 07:29:15 -040086export class TrackPanel extends Panel {
Deepanjan Roy9d95a252018-08-09 10:10:19 -040087 private track: Track;
88 constructor(public trackState: TrackState) {
89 // TODO: Since ES6 modules are asynchronous and it is conceivable that we
90 // want to load a track implementation on demand, we should not rely here on
91 // the fact that the track is already registered. We should show some
92 // default content until a track implementation is found.
Deepanjan Royabd79aa2018-08-28 07:29:15 -040093 super();
Deepanjan Roy9d95a252018-08-09 10:10:19 -040094 const trackCreator = trackRegistry.get(this.trackState.kind);
95 this.track = trackCreator.create(this.trackState);
96 }
97
Primiano Tucci9b5f13e2018-08-10 00:36:19 +010098 getHeight(): number {
99 return this.track.getHeight();
100 }
101
Primiano Tuccif30cd9c2018-08-13 01:53:26 +0200102 updateDom(dom: HTMLElement): void {
Deepanjan Roy9d95a252018-08-09 10:10:19 -0400103 // TODO: Let tracks render DOM in the content area.
104 m.render(
105 dom,
106 m(TrackComponent, {trackState: this.trackState, track: this.track}));
107 }
108
109 renderCanvas(ctx: CanvasRenderingContext2D) {
110 ctx.translate(TRACK_SHELL_WIDTH, 0);
Deepanjan Roy9d95a252018-08-09 10:10:19 -0400111 drawGridLines(
112 ctx,
113 globals.frontendLocalState.timeScale,
Primiano Tuccif30cd9c2018-08-13 01:53:26 +0200114 globals.frontendLocalState.visibleWindowTime,
Primiano Tucci9b5f13e2018-08-10 00:36:19 +0100115 this.track.getHeight());
Deepanjan Roy9d95a252018-08-09 10:10:19 -0400116
Deepanjan Roy9d95a252018-08-09 10:10:19 -0400117 this.track.renderCanvas(ctx);
118 }
Deepanjan Royabd79aa2018-08-28 07:29:15 -0400119}