Encapsulate the file picker code into a view class.

This will allow the mesh debugger to use it.
This commit is contained in:
Patrick Walton 2017-09-20 11:51:20 -07:00
parent 914179763d
commit b732878532
4 changed files with 67 additions and 26 deletions

View File

@ -41,7 +41,9 @@
<option value="font-open-sans">Font: Open Sans</option>
<option value="font-nimbus-sans">Font: Nimbus Sans</option>
<option value="svg-tiger">SVG: Ghostscript Tiger</option>
<option value="svg-custom">SVG: Custom…</option>
</select>
<input id="pf-file-select" type="file">
</div>
<div class="form-group" id="pf-font-path-select-group">
<label for="pf-font-path-label">Path</label>

View File

@ -12,6 +12,7 @@ import {AntialiasingStrategyName} from "./aa-strategy";
import {ShaderLoader, ShaderMap, ShaderProgramSource} from './shader-loader';
import {expectNotNull, unwrapUndef, unwrapNull} from './utils';
import {PathfinderDemoView, Timings, TIMINGS} from "./view";
import { FilePickerView } from "./file-picker";
export abstract class AppController {
start() {
@ -105,12 +106,12 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
}, false);
}
this.filePickerElement = document.getElementById('pf-file-select') as
(HTMLInputElement | null);
if (this.filePickerElement != null) {
this.filePickerElement.addEventListener('change',
event => this.loadFile(event),
false);
this.filePickerView = FilePickerView.create();
if (this.filePickerView != null) {
this.filePickerView.onFileLoaded = fileData => {
this.fileData = fileData;
this.fileLoaded();
};
}
const selectFileElement = document.getElementById('pf-select-file') as
@ -187,23 +188,12 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
this.view.then(view => view.setAntialiasingOptions(aaType, aaLevel, subpixelAA));
}
protected loadFile(event: Event) {
const filePickerElement = event.target as HTMLInputElement;
const file = expectNotNull(filePickerElement.files, "No file selected!")[0];
const reader = new FileReader;
reader.addEventListener('loadend', () => {
this.fileData = reader.result;
this.fileLoaded();
}, false);
reader.readAsArrayBuffer(file);
}
private fileSelectionChanged(event: Event) {
const selectFileElement = event.currentTarget as HTMLSelectElement;
const selectedOption = selectFileElement.selectedOptions[0] as HTMLOptionElement;
if (selectedOption.value === 'load-custom' && this.filePickerElement != null) {
this.filePickerElement.click();
if (selectedOption.value === 'load-custom' && this.filePickerView != null) {
this.filePickerView.open();
const oldSelectedIndex = selectFileElement.selectedIndex;
const newOption = document.createElement('option');
@ -229,7 +219,7 @@ export abstract class DemoAppController<View extends PathfinderDemoView> extends
view: Promise<View>;
protected filePickerElement: HTMLInputElement | null;
protected filePickerView: FilePickerView | null;
protected commonShaderSource: string | null;
protected shaderSources: ShaderMap<ShaderProgramSource> | null;

View File

@ -0,0 +1,43 @@
// pathfinder/client/src/file-picker.ts
//
// Copyright © 2017 The Pathfinder Project Developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
import {expectNotNull} from "./utils";
export class FilePickerView {
private constructor(element: HTMLInputElement) {
this.element = element;
this.onFileLoaded = null;
element.addEventListener('change', event => this.loadFile(event), false);
}
static create(): FilePickerView | null {
const element = document.getElementById('pf-file-select') as (HTMLInputElement | null);
return element == null ? null : new FilePickerView(element);
}
open() {
this.element.click();
}
private loadFile(event: Event) {
const element = event.target as HTMLInputElement;
const file = expectNotNull(element.files, "No file selected!")[0];
const reader = new FileReader;
reader.addEventListener('loadend', () => {
if (this.onFileLoaded != null)
this.onFileLoaded(reader.result);
}, false);
reader.readAsArrayBuffer(file);
}
onFileLoaded: ((fileData: ArrayBuffer) => void) | null;
private readonly element: HTMLInputElement;
}

View File

@ -300,15 +300,15 @@ impl<'a> Partitioner<'a> {
}
fn sort_active_edge_list_and_emit_self_intersections(&mut self, endpoint_index: u32) {
for index in 1..self.active_edges.len() {
for sorted_index in (1..(index + 1)).rev() {
let upper_active_edge_index = (sorted_index - 1) as u32;
let lower_active_edge_index = sorted_index as u32;
loop {
let mut swapped = false;
for lower_active_edge_index in 1..(self.active_edges.len() as u32) {
let upper_active_edge_index = lower_active_edge_index - 1;
if self.active_edges_are_ordered(upper_active_edge_index,
lower_active_edge_index,
endpoint_index) {
break
continue
}
if let Some(crossing_point) =
@ -324,7 +324,13 @@ impl<'a> Partitioner<'a> {
}
}
self.active_edges.swap(sorted_index - 1, sorted_index)
self.active_edges.swap(upper_active_edge_index as usize,
lower_active_edge_index as usize);
swapped = true;
}
if !swapped {
break
}
}
}