diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..2c9c5b7 Binary files /dev/null and b/.DS_Store differ diff --git a/port-companion/.DS_Store b/port-companion/.DS_Store new file mode 100644 index 0000000..fa557e6 Binary files /dev/null and b/port-companion/.DS_Store differ diff --git a/port-companion/device.js b/port-companion/device.js index e598c62..6771301 100644 --- a/port-companion/device.js +++ b/port-companion/device.js @@ -22,8 +22,16 @@ * */ -import { VerticalScroller, VerticalScrollbar, TopScrollerShadow, BottomScrollerShadow, - HorizontalScroller, HorizontalScrollbar, LeftScrollerShadow, RightScrollerShadow } from 'lib/scroller'; +import { + VerticalScroller, + VerticalScrollbar, + TopScrollerShadow, + BottomScrollerShadow, + HorizontalScroller, + HorizontalScrollbar, + LeftScrollerShadow, + RightScrollerShadow +} from 'lib/scroller'; import { DATA, @@ -51,23 +59,44 @@ import { } from "home"; import { - TimingScreen, TimingContent, TimingScreenTemplate, + TimingScreen, + TimingContent, + TimingScreenTemplate, TimingContentTemplate } from "timing"; // the variables: device screen (=content + top / bottom bar + scroller) & device screen's main content export var DeviceScreen; export var DeviceContent; - -// the template: device screen, contains main contents & scroller (without top / bottom navbar on this page) export var DeviceScreenTemplate = Container.template($ => ({ left: 0, right: 0, top: 0, bottom: 0, - skin: whiteSkin, contents: [ VerticalScroller($, { active: true, top: 0, bottom: 0, contents: [ $.DeviceContent, VerticalScrollbar(), TopScrollerShadow(), BottomScrollerShadow(), ] }), ] })); + +// the template: device screen, contains main contents & scroller (without top / bottom navbar on this page) +export var DeviceScreenTemplate = Container.template($ => ({ + left: 0, right: 0, top: 0, bottom: 0, + skin: whiteSkin, + contents: [ + VerticalScroller($, { + active: true, top: 0, bottom: 0, + contents: [ + $.DeviceContent, + VerticalScrollbar(), + TopScrollerShadow(), + BottomScrollerShadow(), + ] + }), + ] +})); // the template: device content, a parameter of device screen's template, contains the main contents -export var DeviceContentTemplate = Column.template($ => ({ top: 0, left: 0, right: 0, contents: [ +export var DeviceContentTemplate = Column.template($ => ({ + top: 0, left: 0, right: 0, + contents: [ new DeviceTopBar({idx: $.idx}), new Line ( { contents: [ - new Picture({ url: DATA.init[$.idx].img, top: 0, left: 0, width: device_image_size, height: device_image_size, }), + new Picture({ + url: DATA.init[$.idx].img, + top: 0, left: 0, width: device_image_size, height: device_image_size, + }), ] }), new Line({height: 20}), @@ -76,7 +105,9 @@ export var DeviceContentTemplate = Column.template($ => ({ top: 0, left: 0, new SettingOptions({label: "TIMING", idx: $.idx}), new Divide({height: 1, length: 200}), new SettingOptions({label: "ALERT", idx: $.idx}), - new Divide({height: 1, length: 200}), ] })); + new Divide({height: 1, length: 200}), + ] +})); // get the annotation string that appears on screen for each option (such as "On/Off" for "TYPE") // called by the template: SettingOptions only @@ -93,7 +124,8 @@ function getStr(idx, option) { // return "24 to 24";// probably showing this way (a proposal) var timing = DATA.init[idx].timing; if (timing) { - return DATA.init[idx].time_start + " to " + DATA.init[idx].time_end; + return "Set"; + //return DATA.init[idx].time_start + " to " + DATA.init[idx].time_end; } return "None"; } @@ -167,7 +199,8 @@ var DeviceTopBar = Container.template($ => ({ new BackTemplate(), new Blank({length: device_list_topbar_width}), ] }), - new Label({ + + new Label({ string: DATA.init[$.idx].DeviceName, style: largeText, }), @@ -185,8 +218,10 @@ var DeviceTopBar = Container.template($ => ({ let BackTemplate = Container.template($ => ({ active: true, contents: [ - new Label({ string: "< BACK", - style: darkGraySmallText, }) + new Label({ + string: "< BACK", + style: darkGraySmallText, + }) ], behavior: Behavior({ onTouchEnded: function(container) { @@ -204,4 +239,4 @@ let BackTemplate = Container.template($ => ({ // just for indentation, similar with Division, nothing special let Blank = Container.template($ => ({ width: $.length, -})); +})); diff --git a/port-companion/files/init_data.json b/port-companion/files/init_data.json index 4ab688c..fe032e2 100644 --- a/port-companion/files/init_data.json +++ b/port-companion/files/init_data.json @@ -27,7 +27,7 @@ }, { "DeviceName":"Oven", - "DeviceGroup":"Kittchen", + "DeviceGroup":"Kitchen", "id": "oven", "type": "binary", "value": 0, diff --git a/port-companion/lib/field.js b/port-companion/lib/field.js new file mode 100644 index 0000000..95f7eed --- /dev/null +++ b/port-companion/lib/field.js @@ -0,0 +1 @@ +import { SystemKeyboard } from 'keyboard'; export class FieldLabelBehavior extends Behavior { onCreate(label, data) { this.data = data; } onDisplayed(label) { this.onEdited(label); } onEdited(label) { } onFocused(label) { label.select(0, label.length); SystemKeyboard.show(); } onKeyDown(label, key, repeat, ticks) { if (key) { var code = key.charCodeAt(0); var edited = false; switch (code) { case 1: /* home */ label.select(0, 0); break; case 2: /* delete selection */ label.insert(); edited = true; break; case 3: /* enter */ return false; case 4: /* end */ label.select(label.length, 0); break; case 5: /* help */ return false; case 8: /* backspace */ if (label.selectionLength == 0) label.select(label.selectionOffset - 1, 1) label.insert() edited = true; break; case 9: /* tab */ return false; case 11: /* page up */ return false; case 12: /* page down */ return false; case 13: /* return */ SystemKeyboard.hide(); break; case 27: /* escape */ return false; case 28: /* left */ if (shiftKey) { label.select(label.selectionOffset - 1, label.selectionLength + 1); } else { if (label.selectionLength == 0) label.select(label.selectionOffset - 1, 0); else label.select(label.selectionOffset, 0); } break; case 29: /* right */ if (shiftKey) label.select(label.selectionOffset, label.selectionLength + 1); else { if (label.selectionLength == 0) label.select(label.selectionOffset + 1, 0); else label.select(label.selectionOffset + label.selectionLength, 0); } break; case 30: /* up */ return false; case 31: /* down */ return false; case 127: /* delete */ if (label.selectionLength == 0) label.select(label.selectionOffset, 1) label.insert() edited = true; break; default: if ((Event.FunctionKeyPlay <= code) && (code <= Event.FunctionKeyPower)) return false; if (code > 0x000F0000) return false; label.insert(key); edited = true; } } else { label.insert() edited = true; } this.onReveal(label); if (edited) this.onEdited(label); return true; } onKeyUp(label, key, repeat, ticks) { if (!key) return false var code = key.charCodeAt(0); var edited = false; switch (code) { case 3: /* enter */ case 5: /* help */ case 9: /* tab */ case 11: /* page up */ case 12: /* page down */ case 27: /* escape */ case 30: /* up */ case 31: /* down */ return false; case 13: /* return */ return label instanceof Text; default: if ((Event.FunctionKeyPlay <= code) && (code <= Event.FunctionKeyPower)) return false; return code <= 0x000F0000; } } onReveal(label) { label.container.reveal(label.selectionBounds); } onTouchBegan(label, id, x, y, ticks) { this.position = label.position; var offset = label.hitOffset(x - this.position.x, y - this.position.y); if (shiftKey) { if (offset < label.selectionOffset) this.anchor = label.selectionOffset + label.selectionLength; else this.anchor = label.selectionOffset; } else this.anchor = offset; this.onTouchMoved(label, id, x, y, ticks); } onTouchCancelled(label, id, x, y, ticks) { } onTouchEnded(label, id, x, y, ticks) { this.onTouchMoved(label, id, x, y, ticks); } onTouchMoved(label, id, x, y, ticks) { this.offset = label.hitOffset(x - this.position.x, y - this.position.y); label.select(this.offset, 0); } onUnfocused(label) { } }; export class FieldScrollerBehavior extends Behavior { onTouchBegan(scroller, id, x, y, ticks) { let label = scroller.first; this.tracking = label.focused; if (this.tracking) label.behavior.onTouchBegan(label, id, x, y, ticks); else label.focus(); } onTouchMoved(scroller, id, x, y, ticks) { let label = scroller.first; if (this.tracking) label.behavior.onTouchMoved(label, id, x, y, ticks); } onTouchEnded(scroller, id, x, y, ticks) { let label = scroller.first; if (this.tracking) label.behavior.onTouchEnded(label, id, x, y, ticks); } } \ No newline at end of file diff --git a/port-companion/lib/keyboard.js b/port-companion/lib/keyboard.js new file mode 100644 index 0000000..0d7b180 --- /dev/null +++ b/port-companion/lib/keyboard.js @@ -0,0 +1 @@ +/* * Copyright (C) 2010-2016 Marvell International Ltd. * Copyright (C) 2002-2010 Kinoma, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ export var SystemKeyboard = { show () { if (!system.keyboard.visible) { system.keyboard.visible = true; } }, hide() { if (system.keyboard.visible) { system.keyboard.visible = false; } } }; \ No newline at end of file diff --git a/port-companion/main.js b/port-companion/main.js index 29d50b4..c5c8ebb 100644 --- a/port-companion/main.js +++ b/port-companion/main.js @@ -8,7 +8,9 @@ */ import { - TMP_SCREEN, img_logo, whiteSkin, + TMP_SCREEN, + img_logo, + whiteSkin, titleText, welcome_img_padding, welcome_img_size, @@ -17,7 +19,15 @@ import { DeviceSimulator, deviceURL, load_data, - DATA, } from "global_settings"; import { Button, ButtonBehavior, RadioGroup, RadioGroupBehavior } from 'lib/buttons'; + DATA, +} from "global_settings"; + +import { + Button, + ButtonBehavior, + RadioGroup, + RadioGroupBehavior +} from 'lib/buttons'; import { HomeContentTemplate, @@ -34,19 +44,36 @@ var size = welcome_img_size; DATA = load_data(); // the button to enter the home page -let enterButtonTemplate = Button.template($ => ({ top: 0, width: 200, right: 0, height: welcome_button_height, contents: [ Label($, {left: 0, right: 0, height: welcome_button_height, string: $.textForLabel, style: buttonText}) ], Behavior: class extends ButtonBehavior { onTap(button){ +let enterButtonTemplate = Button.template($ => ({ + top: 0, width: 200, right: 0, height: welcome_button_height, + contents: [ + Label($, {left: 0, right: 0, height: welcome_button_height, string: $.textForLabel, style: buttonText}) + ], + Behavior: class extends ButtonBehavior { + onTap(button){ application.remove(TMP_SCREEN); HomeContent = HomeContentTemplate({}); LoadHomeContent(HomeContent); HomeScreen = new HomeScreenTemplate({ HomeContent }); TMP_SCREEN = HomeScreen; - application.add(TMP_SCREEN); } - } })); + application.add(TMP_SCREEN); + } + + } +})); -// the welcome page main content var WelcomePageTemplate = Container.template($ => ({ left: 0, right: 0, top: 0, bottom: 0, skin: $.skin, contents: [ +// the welcome page main content +var WelcomePageTemplate = Container.template($ => ({ + left: 0, right: 0, top: 0, bottom: 0, + skin: $.skin, + contents: [ new Column({ top: padding, bottom: padding, - contents: [ new Picture({ url: $.img_url, top: padding, left: padding, right: padding, width: size, height: size, }), + contents: [ + new Picture({ + url: $.img_url, + top: padding, left: padding, right: padding, width: size, height: size, + }), new Label({ string: $.title, style: titleText @@ -54,17 +81,36 @@ let enterButtonTemplate = Button.template($ => ({ top: 0, width: 200, right: new enterButtonTemplate({textForLabel: "ENTER YOUR HOME"}), ] - }), ] })); + }), + ] +})); /* behavior of connecting the devices */ // connected by port -Handler.bind("/discover", Behavior({ onInvoke: function(handler, message){ - trace("found the device.\n"); deviceURL = JSON.parse(message.requestText).url; } })); Handler.bind("/forget", Behavior({ onInvoke: function(handler, message){ - trace("forget the device.\n"); deviceURL = ""; } })); +Handler.bind("/discover", Behavior({ + onInvoke: function(handler, message){ + trace("found the device.\n"); + deviceURL = JSON.parse(message.requestText).url; + } +})); +Handler.bind("/forget", Behavior({ + onInvoke: function(handler, message){ + trace("forget the device.\n"); + deviceURL = ""; + } +})); // will be used to communicate between device and the companion application -var ApplicationBehavior = Behavior.template({ onDisplayed: function(application) { application.discover(DeviceSimulator); // application.add(new HomeScreen({ onOff:"on" })); }, onQuit: function(application) { application.forget(DeviceSimulator); }, }); +var ApplicationBehavior = Behavior.template({ + onDisplayed: function(application) { + application.discover(DeviceSimulator); + // application.add(new HomeScreen({ onOff:"on" })); + }, + onQuit: function(application) { + application.forget(DeviceSimulator); + }, +}); -// initialize the welcome screen +// initialize the welcome screen TMP_SCREEN = new WelcomePageTemplate({ skin: whiteSkin, img_url: img_logo, title: "HoM"}); application.behavior = new ApplicationBehavior(); application.add(TMP_SCREEN); diff --git a/port-companion/timing.js b/port-companion/timing.js index a2f8711..9fe24a7 100644 --- a/port-companion/timing.js +++ b/port-companion/timing.js @@ -1,33 +1,8 @@ -<<<<<<< HEAD -import { VerticalScroller, VerticalScrollbar, TopScrollerShadow, BottomScrollerShadow, HorizontalScroller, HorizontalScrollbar, LeftScrollerShadow, RightScrollerShadow } from 'lib/scroller'; import { DATA, save_data, TMP_SCREEN, largeText, whiteSkin, device_list_item_padding, device_list_topbar_height, // lightGraySmallText, darkGraySmallText } from "global_settings"; import { DeviceScreenTemplate, DeviceContentTemplate, DeviceScreen, DeviceContent } from "device"; export var TimingScreen; export var TimingContent; export var TimingScreenTemplate = Container.template($ => ({ left: 0, right: 0, top: 0, bottom: 0, skin: whiteSkin, contents: [ VerticalScroller($, { active: true, top: 0, bottom: 0, contents: [ $.TimingContent, VerticalScrollbar(), TopScrollerShadow(), BottomScrollerShadow(), ] }), ] })); export var TimingContentTemplate = Column.template($ => ({ top: 0, left: 0, right: 0, contents: [ new TimingTopBar({idx: $.idx}), ] })); var TimingTopBar = Container.template($ => ({ // top-bar top: device_list_item_padding, left: device_list_item_padding, right: device_list_item_padding, bottom: device_list_item_padding, height: device_list_topbar_height, contents: [ new Column( { contents: [ new Line( { contents: [ new BackTemplate({idx: $.idx}), new Blank(), ] }), new Label({ string: "TIMING", style: largeText, }), ]}), ] })); let BackTemplate = Container.template($ => ({ active: true, contents: [ new Label({ string: "< BACK", style: darkGraySmallText, // top: 50, left: 240, right: home_list_item_padding, width: home_list_topbar_img_size, height: home_list_topbar_img_size, }) ], behavior: Behavior({ onTouchEnded: function(container) { save_data(DATA); application.remove(TMP_SCREEN); DeviceContent = DeviceContentTemplate({idx: $.idx}); DeviceScreen = new DeviceScreenTemplate({ DeviceContent }); TMP_SCREEN = DeviceScreen; application.add(TMP_SCREEN); } }) })); let Blank = Container.template($ => ({ width: 250 })); -======= -/* - * this is the part where timing screen is implemented; includes: - * Variables: - * TimingContent - an instance of TimingContentTemplate, timing page's content - * TimingScreen - an instance of TimingScreenTemplate, the whole timing page's screen - * Functions: - * - * Templates: - * TimingScreenTemplate - the template of the whole timing screen - * TimingContentTemplate - serves as a parameter of the whole timing screen's template, contains the main contents - * TimingTopBar - the title part of the timing screen, contains brief discription & back button - * BackTemplate - the "< BACK" button on top left of the screen, - * click it to return to "device" page - * Blank - used completely as an indentation element - * - * - */ +/* * this is the part where timing screen is implemented; includes: * Variables: * TimingContent - an instance of TimingContentTemplate, timing page's content * TimingScreen - an instance of TimingScreenTemplate, the whole timing page's screen * Functions: * * Templates: * TimingScreenTemplate - the template of the whole timing screen * TimingContentTemplate - serves as a parameter of the whole timing screen's template, contains the main contents * TimingTopBar - the title part of the timing screen, contains brief discription & back button * BackTemplate - the "< BACK" button on top left of the screen, * click it to return to "device" page * Blank - used completely as an indentation element * * */ import { VerticalScroller, VerticalScrollbar, TopScrollerShadow, BottomScrollerShadow, HorizontalScroller, HorizontalScrollbar, LeftScrollerShadow, RightScrollerShadow } from 'lib/scroller'; import { FieldScrollerBehavior, FieldLabelBehavior } from 'lib/field'; import { SystemKeyboard } from 'lib/keyboard'; import { DATA, save_data, TMP_SCREEN, largeText, darkGrayMidText, darkGrayMidText_thin, whiteSkin, lightGraySkin, device_list_item_padding, device_list_topbar_height, device_list_setting_height, darkGraySmallText } from "global_settings"; import { DeviceScreenTemplate, DeviceContentTemplate, DeviceScreen, DeviceContent, Divide } from "device"; // instance of templates: screen & content // screen = content + scroller (no topbar / bottombar as nav bar in this case) export var TimingScreen; export var TimingContent; // the template of screen export var TimingScreenTemplate = Container.template($ => ({ left: 0, right: 0, top: 0, bottom: 0, skin: whiteSkin, contents: [ VerticalScroller($, { active: true, top: 0, bottom: 0, contents: [ $.TimingContent, VerticalScrollbar(), TopScrollerShadow(), BottomScrollerShadow(), ] }), ] })); // the template of main contents in the screen export var TimingContentTemplate = Column.template($ => ({ top: 0, left: 0, right: 0, contents: [ new TimingTopBar({idx: $.idx}), new Line({height: 20}), new TimingSettingsOptions({settingName:"Starts",idx:$.idx}), new Divide({height: 1, length: 200}), new TimingSettingsOptions({settingName:"Ends", idx:$.idx}), new Divide({height: 1, length: 200}), new TimingSettingsOptions({settingName:"Repeat", idx:$.idx}), new Divide({height: 1, length: 200}), ] })); // the title part of the timing screen (not real topbar, not sticking to the top, will scroll) var TimingTopBar = Container.template($ => ({ // top-bar top: device_list_item_padding, left: device_list_item_padding, right: device_list_item_padding, bottom: device_list_item_padding, height: device_list_topbar_height, contents: [ new Column( { contents: [ new Line( { contents: [ new BackTemplate({idx: $.idx}), new Blank({length: 200}), new SaveTemplate({idx:$.idx}) ] }), new Label({ string: "TIMING", style: largeText, }), ]}), ] })); var TimingSettingsOptions = Line.template($ => ({ top: device_list_item_padding, left: device_list_item_padding, right: device_list_item_padding, bottom: device_list_item_padding, height: device_list_setting_height, active: true, contents: [ new Label({ string: $.settingName, style: darkGrayMidText_thin, width: 100, }), new Blank({length: 100}), new Label({ string: getTimeSet($.settingName, $.idx), style: darkGrayMidText_thin, width: 60, name: "val", }), ], behavior: Behavior({ onTouchEnded: function(container) { //application.remove(TMP_SCREEN) if ($.settingName == "Starts"){ container.val.string = "2:00 PM"; }else if($.settingName == "Ends"){ container.val.string = "4:00 PM"; } } }), })); -import { VerticalScroller, VerticalScrollbar, TopScrollerShadow, BottomScrollerShadow, HorizontalScroller, HorizontalScrollbar, LeftScrollerShadow, RightScrollerShadow } from 'lib/scroller'; import { DATA, save_data, TMP_SCREEN, largeText, whiteSkin, device_list_item_padding, device_list_topbar_height, darkGraySmallText } from "global_settings"; import { DeviceScreenTemplate, DeviceContentTemplate, DeviceScreen, DeviceContent } from "device"; - -// instance of templates: screen & content -// screen = content + scroller (no topbar / bottombar as nav bar in this case) export var TimingScreen; export var TimingContent; - -// the template of screen export var TimingScreenTemplate = Container.template($ => ({ left: 0, right: 0, top: 0, bottom: 0, skin: whiteSkin, contents: [ VerticalScroller($, { active: true, top: 0, bottom: 0, contents: [ $.TimingContent, VerticalScrollbar(), TopScrollerShadow(), BottomScrollerShadow(), ] }), ] })); -// the template of main contents in the screen export var TimingContentTemplate = Column.template($ => ({ top: 0, left: 0, right: 0, contents: [ new TimingTopBar({idx: $.idx}), ] })); // the title part of the timing screen (not real topbar, not sticking to the top, will scroll) var TimingTopBar = Container.template($ => ({ // top-bar top: device_list_item_padding, left: device_list_item_padding, right: device_list_item_padding, bottom: device_list_item_padding, height: device_list_topbar_height, contents: [ new Column( { contents: [ new Line( { contents: [ new BackTemplate({idx: $.idx}), new Blank(), ] }), new Label({ string: "TIMING", style: largeText, }), ]}), ] })); // the back button "< BACK", click it to go back to device screen let BackTemplate = Container.template($ => ({ active: true, contents: [ new Label({ string: "< BACK", style: darkGraySmallText, }) ], behavior: Behavior({ onTouchEnded: function(container) { save_data(DATA); application.remove(TMP_SCREEN); - DeviceContent = DeviceContentTemplate({idx: $.idx}); - DeviceScreen = new DeviceScreenTemplate({ DeviceContent }); - TMP_SCREEN = DeviceScreen; - application.add(TMP_SCREEN); } }) })); // just for indentation let Blank = Container.template($ => ({ width: 250 })); ->>>>>>> 26626094b195a9df5385bf65fe8dff0fb78f7313 +function translate_time(time_val) { + if(time_val == 14) + return "2:00 PM"; + else if (time_val == 16) + return "4:00 PM"; +} function getTimeSet(settingName, idx){ var timing = DATA.init[idx].timing; // trace("TIMING:"+timing+"\n"); // trace("IDX:"+idx+"\n"); if (timing) { if (settingName == "Starts"){ return translate_time(DATA.init[idx].time_start); } else if (settingName == "Ends"){ return translate_time(DATA.init[idx].time_end); } } return "None"; } // the back button "< BACK", click it to go back to device screen let BackTemplate = Container.template($ => ({ active: true, contents: [ new Label({ string: "< BACK", style: darkGraySmallText, }) ], behavior: Behavior({ onTouchEnded: function(container) { save_data(DATA); application.remove(TMP_SCREEN); DeviceContent = DeviceContentTemplate({idx: $.idx}); DeviceScreen = new DeviceScreenTemplate({ DeviceContent }); TMP_SCREEN = DeviceScreen; application.add(TMP_SCREEN); } }) })); let SaveTemplate = Container.template($ => ({ active: true, contents: [ new Label({ string: "SAVE", style: darkGraySmallText, }) ], behavior: Behavior({ onTouchEnded: function(container) { DATA.init[$.idx].timing = 1; DATA.init[$.idx].time_start = 14; DATA.init[$.idx].time_end = 16; save_data(DATA); } }) })); // just for indentation let Blank = Container.template($ => ({ width: $.length, })); \ No newline at end of file