Skip to content

Commit

Permalink
Merge branch 'propgroup-litcomponent'
Browse files Browse the repository at this point in the history
* propgroup-litcomponent:
  UI: b/pianoroll.js: add todo comment
  UI: b/knob.js: use fixed adjustment factors for wheel events
  UI: util.js: wheel_delta: normalize delta to pixels for modern browsers
	Work around Firefox changing deltaY vs deltaMode depending on the order
	of access! Throw away old compat code.
  UI: b/knob.js: fix invalid field access
  UI: b/propgroup.js: avoid shadowRoot
  UI: util.js: refuse pointer lock grabbing on orphans and shadowRoot descendants
  UI: b/propgroup.js: port to LitComponent
  UI: b/deviceeditor.vue: use b-propgroup
  UI: b/propinput.js: support readonly + disabled state
  UI: b/propinput.js: add support for <b-knob/> as property field
  UI: b/propinput.js: let labeled default to false
  UI: b/toggle.js: store pressed button number
  UI: util.js: add uuname()

Signed-off-by: Tim Janik <[email protected]>
  • Loading branch information
tim-janik committed Aug 30, 2023
2 parents a7ab348 + 10b4a30 commit 3957579
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 199 deletions.
2 changes: 1 addition & 1 deletion ui/b/deviceeditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<h-flex class="b-deviceeditor" @contextmenu.prevent="$refs.deviceeditorcmenu.popup ($event)" >
<span class="b-deviceeditor-sw" > {{ device_info.name }} </span>
<c-grid class="b-deviceeditor-areas" >
<b-pro-group v-for="group in gprops" :key="group.name" :style="group_style (group)"
<b-propgroup v-for="group in gprops" :key="group.name" :style="group_style (group)"
:name="group.name" :props="group.props" />
</c-grid>
<b-contextmenu ref="deviceeditorcmenu" id="g-deviceeditorcmenu" :activate.prop="activate" :isactive.prop="isactive" >
Expand Down
13 changes: 10 additions & 3 deletions ui/b/knob.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ class BKnob extends LitComponent {
wheel (event)
{
const d = Util.wheel_delta (event);
if (this[SPIN_DRAG].captureid === undefined && // not dragging
if (this[SPIN_DRAG]?.captureid === undefined && // not dragging
((!this.hscroll && d.x != 0) ||
(!this.vscroll && d.y != 0)))
return; // only consume scroll events if enabled
Expand Down Expand Up @@ -380,14 +380,21 @@ function spin_drag_change ()
/// Calculate spin drag acceleration (slowdown) from event type and modifiers.
function spin_drag_granularity (event)
{
if (event.type == 'wheel') {
let gran = 0.025; // approximate wheel delta "step" to percent
if (event.shiftKey)
gran = 0.005; // slow down
else if (event.ctrlKey)
gran = 0.10; // speed up
return gran;
}
// pixel drag
const radius = 64; // assumed knob size
const circum = 2 * radius * Math.PI;
let gran = 1 / circum; // steps per full turn to feel natural
if (event.shiftKey)
gran = gran * 0.1; // slow down
else if (event.ctrlKey)
gran = gran * 10; // speed up
if (event.type == 'wheel')
gran /= 2; // approximate mouse movements in pixels
return gran;
}
1 change: 1 addition & 0 deletions ui/b/pianoroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ class BPianoRoll extends LitComponent {
}
wheel (event)
{
// TODO: use "scroll" for scrollbars, wheel delta is inappropriate
const delta = Util.wheel_delta (event);
if (Math.abs (delta.x) > Math.abs (delta.y))
this.hscrollbar.scrollBy ({ left: delta.x });
Expand Down
125 changes: 0 additions & 125 deletions ui/b/pro-group.vue

This file was deleted.

115 changes: 115 additions & 0 deletions ui/b/propgroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// This Source Code Form is licensed MPL-2.0: http://mozilla.org/MPL/2.0

/** @class B-PROPGROUP
* A property group is a collection of properties.
* @property {string} name - Group name.
* @property {Array<any>} props - List of properties with cached information and layout rows.
* @property {boolean} readonly - Make this component non editable for the user.
*/

import { LitComponent, html, JsExtract, docs } from '../little.js';
import * as Util from '../util.js';

// == STYLE ==
JsExtract.scss`
b-propgroup {
@include v-flex();
padding: 5px;
justify-content: space-evenly;
border-radius: $b-button-radius;
background: $b-device-area1;
&:nth-child(2n) {
background: $b-device-area2;
}
.b-propgroup-title {
display: flex;
justify-content: center;
text-align: center;
flex-grow: 1;
}
.b-propgroup-input {
flex-grow: 1;
}
.b-propgroup-row {
justify-content: space-evenly;
.b-propgroup-vprop {
align-items: center;
.b-propgroup-nick {
font-size: 90%;
}
}
//* emulate: .b-propgroup-row { gap: ...; } */
& > *:not(:last-child) { margin-right: 7px; }
}
//* emulate: .b-propgroup { gap: ...; } */
& > *:not(:last-child) { margin-bottom: 5px; }
.b-propgroup-big {
/*max-height: 2em;*/
}
}`;

// == HTML ==
const GROUP_HTML = (t, proprows) => [
html`
<span class="b-propgroup-title"> ${t.name} </span> `,
proprows.map ((row, index) => html`
<h-flex class="b-propgroup-row" key="${index}">
${row.map (prop => PROP_HTML (t, prop))}
</h-flex>`),
];
const PROP_HTML = (t, prop) => html`
<v-flex class=${t.prop_class (prop) + " b-propgroup-vprop"}>
<b-propinput class="b-propgroup-input" .prop="${prop}" ?readonly=${t.readonly}></b-propinput>
<span class="b-propgroup-nick"> ${prop.nick_} </span>
</v-flex>`;

// == SCRIPT ==
class BPropGroup extends LitComponent {
createRenderRoot() { return this; }
render()
{
const proprows = this.assign_layout_rows (this.props);
return GROUP_HTML (this, proprows);
}
static properties = {
name: { type: String, reflect: true },
props: { type: Array, reflect: true },
readonly: { type: Boolean, reflect: true },
};
constructor()
{
super();
this.name = '';
this.props = [];
this.readonly = false;
}
updated (changed_properties)
{
if (changed_properties.has ('props'))
; // proprows are generated on the fly
}
prop_class (prop)
{
const hints = ':' + prop.hints_ + ':';
let c = '';
if (prop.is_numeric_ && hints.search (/:big:/) < 0) // FIXME: test "big" hint
c += 'b-propgroup-big';
return c;
}
assign_layout_rows (props)
{
// split properties into rows, according to lrow_
const rows = [];
for (const prop of props) {
console.assert ('number' == typeof prop.lrow_);
if (!rows[prop.lrow_]) {
rows[prop.lrow_] = [];
rows[prop.lrow_].index = prop.lrow_;
}
rows[prop.lrow_].push (prop);
}
// freezing avoids watchers
return Object.freeze (rows);
}
}
customElements.define ('b-propgroup', BPropGroup);
37 changes: 27 additions & 10 deletions ui/b/propinput.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,28 @@ JsExtract.scss`
z-index: 9;
}
&.b-propinput:hover .b-propinput-span { overflow: visible; }
}`;
}
.b-propinput-readonly {
filter: contrast(50%) brightness(50%);
&[disabled] {
pointer-events: none;
}
}
`;

// == HTML ==
const HTML = (t, d) => [
t.istype ('knob') &&
html`
<b-knob class=${t.classes + " b-propinput-toggle"} label="" ?disabled=${t.readonly}
.prop="${t.prop}" ></b-toggle>`,
t.istype ('toggle') &&
html`
<b-toggle class="b-propinput-toggle" label=""
<b-toggle class=${t.classes + " b-propinput-toggle"} label="" ?disabled=${t.readonly}
.value=${t.prop.value_.num} @valuechange=${e => t.set_num (e.target.value)} ></b-toggle>`,
t.istype ('choice') &&
html`
<b-choiceinput class="b-propinput-choice" small="1" indexed="1"
<b-choiceinput class=${t.classes + " b-propinput-choice"} small="1" indexed="1" ?disabled=${t.readonly}
value=${t.prop.value_.val} @valuechange=${e => t.prop.apply_ (e.target.value)}
label=${t.prop.label_} title=${t.prop.title_} .choices=${t.prop.value_.choices} ></b-choiceinput>`,
!t.labeled || !t.prop.nick_ ? '' :
Expand All @@ -69,7 +80,7 @@ class BPropInput extends LitComponent {
constructor()
{
super();
this.labeled = true;
this.labeled = false;
this.readonly = false;
this.prop = null;
}
Expand All @@ -85,6 +96,9 @@ class BPropInput extends LitComponent {
{
this.prop && this.prop.delnotify_ (this.request_update_);
}
get classes() {
return this.readonly ? 'b-propinput-readonly' : '';
}
value_changed()
{
if (!this.prop) {
Expand All @@ -105,17 +119,20 @@ class BPropInput extends LitComponent {
this.setAttribute ('data-bubble', b);
App.zmove(); // force bubble changes to be picked up
}
istype (proptyppe)
istype (proptype)
{
if (this.prop?.is_numeric_)
{
const hints = ':' + this.prop.hints_ + ':';
if (proptyppe === 'toggle' && hints.search (/:toggle:/) >= 0)
return true;
if (proptyppe === 'choice' && hints.search (/:choice:/) >= 0)
return true;
let ptype = 'knob';
if (hints.search (/:choice:/) >= 0)
ptype = 'choice';
else if (hints.search (/:toggle:/) >= 0)
ptype = 'toggle';
if (proptype === ptype)
return true; // allow html`` eval
}
return '';
return ''; // empty html``
}
set_num (nv)
{
Expand Down
Loading

0 comments on commit 3957579

Please sign in to comment.