Source: addons/hmd_conf.js

  1. import register from "../util/register.js";
  2. import m_cont_fact from "../extern/container.js";
  3. import m_ctl_fact from "../extern/controls.js";
  4. import m_input_fact from "../extern/input.js";
  5. import m_print_fact from "../intern/print.js";
  6. import m_storage_fact from "./storage.js";
  7. import m_util_fact from "../extern/util.js";
  8. /**
  9. * HMD configurator add-on.
  10. * @module hmd_conf
  11. */
  12. function HMD_config(ns, exports) {
  13. var m_cont = m_cont_fact(ns);
  14. var m_ctl = m_ctl_fact(ns);
  15. var m_input = m_input_fact(ns);
  16. var m_print = m_print_fact(ns);
  17. var m_storage = m_storage_fact(ns);
  18. var m_util = m_util_fact(ns);
  19. var _is_shown = false;
  20. var _hmd_dialog = null;
  21. var _style = null;
  22. var _hmd_list = null;
  23. var _update = true;
  24. var _param_values = {
  25. "profile": "custom",
  26. "first_distortion": 0,
  27. "second_distortion": 0,
  28. "bevel_size": 0,
  29. "screen_width": 0,
  30. "screen_height": 0,
  31. "screen_lense": 0,
  32. "ipd": 0,
  33. "baseline": 0
  34. };
  35. var DEFAULT_FIRST_DISTORTION = 0.34;
  36. var DEFAULT_SECOND_DISTORTION = 0.55;
  37. var DEFAULT_BEVEL_SIZE = 4;
  38. var DEFAULT_SCREEN_WIDTH = 110;
  39. var DEFAULT_SCREEN_HEIGHT = 65;
  40. var DEFAULT_SCREEN_LENSE_DIST = 50;
  41. var DEFAULT_EYE_DISTANCE = 64;
  42. var DEFAULT_BASELINE_DIST = 32;
  43. var INCH_TO_MM = 25.4;
  44. var IS_IOS = /iPad|iPhone|iPod/.test(navigator.platform);
  45. var UPDATE_DELAY = 1000;
  46. var MM_TO_M = 1 / 1000;
  47. var P_COMMON = 0;
  48. var P_MOBILE = 1;
  49. var P_WEBVR = 2;
  50. // use braces to prevent a obfuscation
  51. var _viewer_profiles = {
  52. "oculus_dk2": {
  53. name: "Oculus Rift DK2",
  54. type: P_WEBVR,
  55. "first_distortion": 0.22,
  56. "second_distortion": 0.28
  57. // don't forget to place comma if you uncomment the next line
  58. // chromatic_aberration_coefs: [-0.015, 0.02, 0.025, 0.02]
  59. },
  60. "cardboard_1": {
  61. name: "Cardboard (2014)",
  62. type: P_MOBILE,
  63. "ipd": 60,
  64. "baseline": 35,
  65. "screen_lense": 42,
  66. "first_distortion": 0.441,
  67. "second_distortion": 0.156
  68. // don't forget to place comma if you uncomment the next line
  69. // chromatic_aberration_coefs : [0.0, 0.0, 0.0, 0.0]
  70. },
  71. "cardboard_2": {
  72. name: "Cardboard (2015)",
  73. type: P_MOBILE,
  74. "ipd": 64,
  75. "baseline": 35,
  76. "screen_lense": 39,
  77. "first_distortion": 0.34,
  78. "second_distortion": 0.55
  79. // don't forget to place comma if you uncomment the next line
  80. // chromatic_aberration_coefs : [0.0, 0.0, 0.0, 0.0]
  81. },
  82. "custom": {
  83. name: "Custom",
  84. type: P_COMMON,
  85. "ipd": 64,
  86. "baseline": 35,
  87. "screen_lense": 39,
  88. "first_distortion": 0.0,
  89. "second_distortion": 0.0
  90. // don't forget to place comma if you uncomment the next line
  91. // chromatic_aberration_coefs: [0.0, 0.0, 0.0, 0.0]
  92. }
  93. }
  94. var _param_list = [{
  95. label: "Tray to lens-center distance.",
  96. is_mobile: true,
  97. inputs: [{
  98. id: "baseline",
  99. max: "50",
  100. step: "0.5"
  101. }
  102. ]
  103. }, {
  104. label: "Interpupillary distance.",
  105. is_mobile: true,
  106. inputs: [{
  107. id: "ipd",
  108. max: "100",
  109. step: "1"
  110. }
  111. ]
  112. }, {
  113. label: "Screen to lense distance.",
  114. is_mobile: true,
  115. inputs: [{
  116. id: "screen_lense",
  117. max: "100",
  118. step: "1"
  119. }
  120. ]
  121. }, {
  122. label: "Screen height.",
  123. is_mobile: true,
  124. inputs: [{
  125. id: "screen_height",
  126. max: "150",
  127. step: "1"
  128. }
  129. ]
  130. }, {
  131. label: "Screen width.",
  132. is_mobile: true,
  133. inputs: [{
  134. id: "screen_width",
  135. max: "200",
  136. step: "1"
  137. }
  138. ]
  139. }, {
  140. label: "Bevel width.",
  141. is_mobile: true,
  142. inputs: [{
  143. id: "bevel_size",
  144. max: "20",
  145. step: "1"
  146. }
  147. ]
  148. }, {
  149. label: "Distortion coefficients.",
  150. inputs: [{
  151. id: "first_distortion",
  152. max: "1.0",
  153. step: "0.01"
  154. }, {
  155. id: "second_distortion",
  156. max: "1.0",
  157. step: "0.01"
  158. }
  159. ]
  160. }
  161. ]
  162. /**
  163. * Check if HMD configurator can be shown.
  164. * @method module:hmd_conf.check
  165. * @returns {boolean} The result of the checking.
  166. */
  167. exports.check = check;
  168. function check() {
  169. if (!m_input.can_use_device(m_input.DEVICE_HMD))
  170. return false;
  171. var device = m_input.get_device_by_type_element(m_input.DEVICE_HMD);
  172. var hmd_type = m_input.get_value_param(device, m_input.HMD_WEBVR_TYPE);
  173. return (hmd_type & (m_input.HMD_NON_WEBVR | m_input.HMD_WEBVR_MOBILE |
  174. m_input.HMD_WEBVR_DESKTOP)) &&
  175. !(hmd_type & m_input.HMD_WEBVR1);
  176. }
  177. /**
  178. * Show HMD configurator.
  179. * @method module:hmd_conf.show
  180. * @param {string} css_class CSS class of HMD configurator element
  181. */
  182. exports.show = function(css_class) {
  183. if (!check())
  184. return;
  185. var container = m_cont.get_container();
  186. _style = document.createElement("style");
  187. _style.innerHTML = "." + css_class + " input[type=range]::-webkit-slider-runnable-track {width: 100%; height: 8px;cursor: pointer;background-color: #fff;border: 2px solid rgba(98, 98, 98, .2);box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);}." + css_class + " input[type=range]::-webkit-slider-thumb {box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);height: 30px;width: 16px;border-radius: 2px;background-color: #323232;cursor: pointer;margin-top: -13px;-webkit-appearance: none;}";
  188. document.head.appendChild(_style);
  189. if (_is_shown)
  190. return;
  191. _is_shown = true;
  192. restore_params();
  193. var mdevice = m_input.get_device_by_type_element(m_input.DEVICE_MOUSE, container);
  194. m_input.switch_prevent_default(mdevice, false);
  195. var tdevice = m_input.get_device_by_type_element(m_input.DEVICE_TOUCH, container);
  196. m_input.switch_prevent_default(tdevice, false);
  197. _hmd_dialog = document.createElement("div");
  198. _hmd_dialog.className = css_class;
  199. container.appendChild(_hmd_dialog);
  200. _hmd_list = document.createElement("div");
  201. _hmd_dialog.appendChild(_hmd_list)
  202. _hmd_list.style.cssText =
  203. "background-color: #484848;" +
  204. "border: 2px solid rgba(150, 150, 150, 0.7);" +
  205. "box-shadow: 0px 0px 10px 0px rgba(150, 150, 150, 0.7);" +
  206. "position: relative;" +
  207. "width: 524px;" +
  208. "padding: 16px;" +
  209. "overflow: hidden;";
  210. var select = create_profiles_select();
  211. _hmd_list.appendChild(select);
  212. var device = m_input.get_device_by_type_element(m_input.DEVICE_HMD);
  213. for (var i = 0; i < _param_list.length; i++) {
  214. if (m_input.get_value_param(device, m_input.HMD_WEBVR_TYPE) &
  215. (m_input.HMD_NON_WEBVR | m_input.HMD_WEBVR_MOBILE) ||
  216. !_param_list[i].is_mobile) {
  217. var param_cont = create_param(_param_list[i], i);
  218. _hmd_list.appendChild(param_cont);
  219. }
  220. }
  221. var buttons = create_buttons();
  222. _hmd_list.appendChild(buttons);
  223. var time = m_ctl.create_timeline_sensor();
  224. var last_update_time = 0;
  225. function update_cb(obj, id, pulse) {
  226. var time = m_ctl.get_sensor_value(obj, id, 0);
  227. if (time - last_update_time > UPDATE_DELAY) {
  228. last_update_time = time;
  229. update_params();
  230. }
  231. }
  232. m_ctl.create_sensor_manifold(null, "UPDATE_HMD_RENDERING",
  233. m_ctl.CT_CONTINUOUS, [time], null, update_params);
  234. }
  235. function create_profiles_select() {
  236. var hmd_conf_str = m_storage.get("hmd_conf", "b4w");
  237. var hmd_conf_data = JSON.parse(hmd_conf_str? hmd_conf_str: "{}");
  238. var cur_profile = hmd_conf_data["profile"] || "custom";
  239. var select_cont = document.createElement("div");
  240. var label = document.createElement("label");
  241. label.innerHTML = "Profile: ";
  242. label.className = "text_label";
  243. label.style.cssText =
  244. "background-color: #323232;" +
  245. "border: 2px solid rgba(98, 98, 98, .2);" +
  246. "border-radius: 2px;" +
  247. "width: 120px;" +
  248. "height: 30px;" +
  249. "display: block;" +
  250. "float: left;" +
  251. "font-size: 16px;" +
  252. "font-weight: normal;" +
  253. "color: #fff;" +
  254. "cursor: pointer;" +
  255. "text-decoration: none;" +
  256. "text-align: left;" +
  257. "padding-left: 8px;" +
  258. "line-height: 28px;" +
  259. "margin-bottom: 4px;" +
  260. "box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);";
  261. select_cont.appendChild(label);
  262. var select = document.createElement("select");
  263. select_cont.appendChild(select);
  264. select.style.cssText =
  265. "background-color: #323232;" +
  266. "border: 2px solid rgba(98, 98, 98, .2);" +
  267. "border-radius: 2px;" +
  268. "height: 30px;" +
  269. "display: block;" +
  270. "font-size: 16px;" +
  271. "font-weight: normal;" +
  272. "color: #fff;" +
  273. "cursor: pointer;" +
  274. "text-decoration: none;" +
  275. "text-align: left;" +
  276. "padding-left: 8px;" +
  277. "line-height: 28px;" +
  278. "margin-bottom: 4px;" +
  279. "box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);";
  280. var device = m_input.get_device_by_type_element(m_input.DEVICE_HMD);
  281. if (device)
  282. for (var i in _viewer_profiles) {
  283. if (_viewer_profiles[i].type == P_COMMON ||
  284. (m_input.get_value_param(device, m_input.HMD_WEBVR_TYPE) &
  285. (m_input.HMD_NON_WEBVR | m_input.HMD_WEBVR_MOBILE) &&
  286. _viewer_profiles[i].type == P_MOBILE)) {
  287. var option = document.createElement("option");
  288. option.value = i;
  289. option.text = _viewer_profiles[i].name;
  290. select.appendChild(option);
  291. }
  292. }
  293. select.value = cur_profile;
  294. if (m_util.is_ie11())
  295. select.onchange = change_select_cb;
  296. else
  297. select.oninput = change_select_cb;
  298. return select_cont;
  299. }
  300. function change_select_cb(e){
  301. var profile = e.target.value;
  302. var profile_data = _viewer_profiles[profile];
  303. for (var name in _param_values) {
  304. if (name in profile_data) {
  305. var slider = document.getElementById(name + "_slider");
  306. if (slider) {
  307. slider.disabled = profile !== "custom";
  308. slider.value = profile_data[name];
  309. }
  310. var number = document.getElementById(name + "_number");
  311. if (number) {
  312. number.disabled = profile !== "custom";
  313. number.value = profile_data[name];
  314. }
  315. _param_values[name] = profile_data[name];
  316. }
  317. }
  318. }
  319. /**
  320. * Hide HMD configurator.
  321. * @method module:hmd_conf.hide
  322. */
  323. exports.hide = hide;
  324. function hide() {
  325. m_ctl.remove_sensor_manifold(null, "UPDATE_HMD_RENDERING");
  326. restore_params();
  327. update_params();
  328. if (!_is_shown)
  329. return;
  330. _is_shown = false;
  331. remove_dom_tree();
  332. }
  333. /**
  334. * Reset values of HMD config.
  335. * @method module:hmd_conf.reset
  336. */
  337. exports.reset = reset;
  338. function reset() {
  339. restore_params(true);
  340. update_params();
  341. update_dom_tree();
  342. }
  343. /**
  344. * Update HMD device config without showing HMD configurator
  345. * @method module:hmd_conf.update
  346. */
  347. exports.update = function() {
  348. restore_params();
  349. update_params();
  350. }
  351. function update_dom_tree() {
  352. for (var i in _param_values) {
  353. var slider = document.getElementById(i + "_slider");
  354. if (slider)
  355. slider.value = _param_values[i];
  356. var number = document.getElementById(i + "_number");
  357. if (number)
  358. number.value = _param_values[i];
  359. }
  360. }
  361. function remove_dom_tree() {
  362. var container = m_cont.get_container();
  363. container.removeChild(_hmd_dialog);
  364. document.head.removeChild(_style);
  365. _hmd_dialog = null;
  366. _hmd_list = null;
  367. _style = null;
  368. }
  369. function get_screen_width() {
  370. return Math.max(window.screen.width, window.screen.height) *
  371. window.devicePixelRatio;
  372. }
  373. function get_screen_height() {
  374. return Math.min(window.screen.width, window.screen.height) *
  375. window.devicePixelRatio;
  376. }
  377. function check_rule(rule, ua, screenWidth, screenHeight) {
  378. return (rule["ua"] && ua.indexOf(rule["ua"]) >= 0) ||
  379. !rule["ua"] && rule["res"] && rule["res"][0] && rule["res"][1] &&
  380. Math.min(screenWidth, screenHeight) == Math.min(rule["res"][0], rule["res"][1]) &&
  381. Math.max(screenWidth, screenHeight) == Math.max(rule["res"][0], rule["res"][1]);
  382. }
  383. function find_device_index(dpdb, user_agent, width, height) {
  384. if (dpdb["format"] != 1 || !dpdb["devices"] || !dpdb["devices"].length) {
  385. m_print.error("DPDB isn't correct.");
  386. return -1;
  387. }
  388. for (var i = 0; i < dpdb["devices"].length; i++) {
  389. var device = dpdb["devices"][i];
  390. if (!device["rules"] ||
  391. (device["type"] != "ios" || !IS_IOS) && device["type"] != "android")
  392. continue;
  393. var found = false;
  394. for (var j = 0; j < device["rules"].length; j++) {
  395. var rule = device["rules"][j];
  396. if (check_rule(rule, user_agent, width, height)) {
  397. found = true;
  398. break;
  399. }
  400. }
  401. if (found)
  402. return i;
  403. }
  404. return -1;
  405. }
  406. function restore_params(ignore_storage) {
  407. var user_agent = navigator.userAgent || navigator.vendor || window.opera;
  408. var width = get_screen_width();
  409. var height = get_screen_height();
  410. var width_dpmm = 0;
  411. var height_dpmm = 0;
  412. var bevel_mm = 0;
  413. var device_index = find_device_index(DPDB, user_agent, width, height);
  414. if (device_index != -1) {
  415. var device = DPDB["devices"][device_index];
  416. var xdpi = device["dpi"][0] || device["dpi"];
  417. var ydpi = device["dpi"][1] || device["dpi"];
  418. width_dpmm = Math.round(width * INCH_TO_MM / xdpi);
  419. height_dpmm = Math.round(height * INCH_TO_MM / ydpi);
  420. bevel_mm = Math.round(device["bw"]);
  421. }
  422. var hmd_conf_str = m_storage.get("hmd_conf", "b4w");
  423. var hmd_conf_data = JSON.parse(hmd_conf_str? hmd_conf_str: "{}");
  424. if (ignore_storage) {
  425. _param_values["first_distortion"] = DEFAULT_FIRST_DISTORTION;
  426. _param_values["second_distortion"] = DEFAULT_SECOND_DISTORTION;
  427. _param_values["bevel_size"] = bevel_mm || DEFAULT_BEVEL_SIZE;
  428. _param_values["screen_width"] = width_dpmm || DEFAULT_SCREEN_WIDTH;
  429. _param_values["screen_height"] = height_dpmm || DEFAULT_SCREEN_HEIGHT;
  430. _param_values["screen_lense"] = DEFAULT_SCREEN_LENSE_DIST;
  431. _param_values["ipd"] = DEFAULT_EYE_DISTANCE;
  432. _param_values["baseline"] = DEFAULT_BASELINE_DIST;
  433. } else {
  434. _param_values["first_distortion"] = "first_distortion" in hmd_conf_data?
  435. parseFloat(hmd_conf_data["first_distortion"]):
  436. DEFAULT_FIRST_DISTORTION;
  437. _param_values["second_distortion"] = "second_distortion" in hmd_conf_data?
  438. parseFloat(hmd_conf_data["second_distortion"]):
  439. DEFAULT_SECOND_DISTORTION;
  440. _param_values["bevel_size"] = "bevel_size" in hmd_conf_data?
  441. parseFloat(hmd_conf_data["bevel_size"]):
  442. bevel_mm || DEFAULT_BEVEL_SIZE;
  443. _param_values["screen_width"] = "screen_width" in hmd_conf_data?
  444. parseFloat(hmd_conf_data["screen_width"]):
  445. width_dpmm || DEFAULT_SCREEN_WIDTH;
  446. _param_values["screen_height"] = "screen_height" in hmd_conf_data?
  447. parseFloat(hmd_conf_data["screen_height"]):
  448. height_dpmm || DEFAULT_SCREEN_HEIGHT;
  449. _param_values["screen_lense"] = "screen_lense" in hmd_conf_data?
  450. parseFloat(hmd_conf_data["screen_lense"]):
  451. DEFAULT_SCREEN_LENSE_DIST;
  452. _param_values["ipd"] = "ipd" in hmd_conf_data?
  453. parseFloat(hmd_conf_data["ipd"]): DEFAULT_EYE_DISTANCE;
  454. _param_values["baseline"] = "baseline" in hmd_conf_data?
  455. parseFloat(hmd_conf_data["baseline"]): DEFAULT_BASELINE_DIST;
  456. }
  457. _update = true;
  458. }
  459. function save_changes() {
  460. m_storage.set("hmd_conf", JSON.stringify(_param_values), "b4w");
  461. hide();
  462. }
  463. function update_params() {
  464. if (_update) {
  465. var device = m_input.get_device_by_type_element(m_input.DEVICE_HMD);
  466. if (device) {
  467. m_input.set_config(device, m_input.HMD_DISTORTION,
  468. [_param_values["first_distortion"], _param_values["second_distortion"]]);
  469. if (m_input.get_value_param(device, m_input.HMD_WEBVR_TYPE) &
  470. (m_input.HMD_NON_WEBVR | m_input.HMD_WEBVR_MOBILE)) {
  471. m_input.set_config(device, m_input.HMD_BEVEL_SIZE,
  472. _param_values["bevel_size"] * MM_TO_M);
  473. m_input.set_config(device, m_input.HMD_SCREEN_WIDTH,
  474. _param_values["screen_width"] * MM_TO_M);
  475. m_input.set_config(device, m_input.HMD_SCREEN_HEIGHT,
  476. _param_values["screen_height"] * MM_TO_M);
  477. m_input.set_config(device, m_input.HMD_SCREEN_LENS_DIST,
  478. _param_values["screen_lense"] * MM_TO_M);
  479. m_input.set_config(device, m_input.HMD_EYE_DISTANCE,
  480. _param_values["ipd"] * MM_TO_M);
  481. m_input.set_config(device, m_input.HMD_BASELINE_DIST,
  482. _param_values["baseline"] * MM_TO_M);
  483. }
  484. }
  485. _update = false;
  486. }
  487. }
  488. function change_slider_cb(e) {
  489. var id = e.target.id;
  490. var id_list = id.split("_");
  491. var value_id = id_list.splice(0, id_list.length - 1).join("_");
  492. if (value_id in _param_values && _param_values[value_id] != e.target.value) {
  493. _update = true;
  494. _param_values[value_id] = e.target.value;
  495. var slider = document.getElementById(value_id + "_slider");
  496. slider.value = e.target.value;
  497. var number = document.getElementById(value_id + "_number");
  498. number.value = e.target.value;
  499. }
  500. }
  501. function create_param(param, i) {
  502. var param_cont = document.createElement("div");
  503. var label_d = document.createElement("label");
  504. label_d.className = "text_label";
  505. var margin_right = "8px";
  506. if (i%2)
  507. margin_right = "0";
  508. label_d.style.cssText =
  509. "background-color: #323232;" +
  510. "border: 2px solid rgba(98, 98, 98, .2);" +
  511. "border-radius: 2px;" +
  512. "width: 100%;" +
  513. "height: 30px;" +
  514. "display: block;" +
  515. "font-size: 16px;" +
  516. "font-weight: normal;" +
  517. "color: #fff;" +
  518. "cursor: pointer;" +
  519. "text-decoration: none;" +
  520. "text-align: left;" +
  521. "padding-left: 8px;" +
  522. "line-height: 28px;" +
  523. "margin-bottom: 4px;" +
  524. "box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);";
  525. label_d.textContent = param.label;
  526. param_cont.appendChild(label_d);
  527. param_cont.style.cssText =
  528. "margin-top: 16px;" +
  529. "float: left;" +
  530. "width: 240px;" +
  531. "margin-right: " + margin_right + ";" +
  532. "border-top: 2px solid rgba(98, 98, 98, .4);" +
  533. "box-sizing: border-box;" +
  534. "-webkit-box-sizing: border-box;" +
  535. "padding-top: 8px;";
  536. for (var j = 0; j < param.inputs.length; j++) {
  537. var input_data = param.inputs[j];
  538. var slider = create_slider(input_data);
  539. param_cont.appendChild(slider);
  540. }
  541. return param_cont;
  542. }
  543. function create_slider(input_data) {
  544. var container = document.createElement("div");
  545. container.className = "row";
  546. var input_s = document.createElement("input");
  547. input_s.className = "input_slider";
  548. input_s.style.cssText =
  549. "-webkit-appearance: none;" +
  550. "width: 192px;" +
  551. "display: block;" +
  552. "float: left;" +
  553. "height: 8px;" +
  554. "margin-bottom: 16px;" +
  555. "margin-top: 16px;" +
  556. "box-sizing: border-box;" +
  557. "margin-right: 8px;" +
  558. "margin-left: 0;";
  559. input_s.setAttribute("id", input_data.id + "_slider");
  560. input_s.setAttribute("type", "range");
  561. input_s.setAttribute("min", "0.00");
  562. input_s.setAttribute("step", input_data.step);
  563. input_s.setAttribute("value", _param_values[input_data.id]);
  564. input_s.setAttribute("max", input_data.max);
  565. container.appendChild(input_s);
  566. var input_d = document.createElement("input");
  567. input_d.className = "input_text";
  568. input_d.setAttribute("id", input_data.id + "_number");
  569. input_d.setAttribute("type", "number");
  570. input_d.setAttribute("min", "0.00");
  571. input_d.setAttribute("step", input_data.step);
  572. input_d.setAttribute("value", _param_values[input_data.id]);
  573. input_d.setAttribute("max", input_data.max);
  574. container.appendChild(input_d);
  575. input_d.style.cssText =
  576. "background-color: #323232;" +
  577. "border: 2px solid rgba(98, 98, 98, .2);" +
  578. "border-radius: 2px;" +
  579. "width: 40px;" +
  580. "height: 30px;" +
  581. "display: block;" +
  582. "float: left;" +
  583. "font-size: 16px;" +
  584. "font-weight: normal;" +
  585. "color: #fff;" +
  586. "cursor: pointer;" +
  587. "text-decoration: none;" +
  588. "text-align: center;" +
  589. "box-sizing: border-box;" +
  590. "line-height: 28px;" +
  591. "margin-top: 4px;" +
  592. "margin-right: 0;" +
  593. "margin-left: 0;" +
  594. "box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);";
  595. if (m_util.is_ie11()) {
  596. input_s.onchange = change_slider_cb;
  597. input_d.onchange = change_slider_cb;
  598. } else {
  599. input_s.oninput = change_slider_cb;
  600. input_d.oninput = change_slider_cb;
  601. }
  602. return container;
  603. }
  604. function create_buttons() {
  605. var buttons_container = document.createElement("div");
  606. var hmd_submit_button = create_button(save_changes, "SAVE", "4px");
  607. var hmd_cancel_button = create_button(hide, "CANCEL", "4px");
  608. var hmd_reset_button = create_button(reset, "RESET", "0px");
  609. buttons_container.className = "row";
  610. buttons_container.style.cssText =
  611. "padding-top: 32px;" +
  612. "clear: both;" +
  613. "box-sizing: border-box;" +
  614. "-webkit-box-sizing: border-box;";
  615. buttons_container.appendChild(hmd_submit_button);
  616. buttons_container.appendChild(hmd_cancel_button);
  617. buttons_container.appendChild(hmd_reset_button);
  618. // var common_style = "margin: 20px 0;" +
  619. // "border: 0;" +
  620. // "background-color: #337ab7;" +
  621. // "border-radius: 4px;" +
  622. // "margin-right:10px;" +
  623. // "color:#fff;" +
  624. // "padding: 10px 15px;" +
  625. // "margin-right: 5px;" +
  626. // "cursor:pointer;";
  627. // hmd_submit_button.style.cssText = common_style;
  628. // hmd_cancel_button.style.cssText = common_style;
  629. // hmd_reset_button.style.cssText = common_style;
  630. return buttons_container;
  631. }
  632. function create_button(callback, text_content, margin_right) {
  633. var button = document.createElement("button");
  634. button.onclick = callback;
  635. button.style.cssText =
  636. "background-color: #323232;" +
  637. "border: 2px solid rgba(98, 98, 98, .2);" +
  638. "border-radius: 2px;" +
  639. "width: 160px;" +
  640. "height: 30px;" +
  641. "display: block;" +
  642. "float: left;" +
  643. "font-size: 16px;" +
  644. "font-weight: normal;" +
  645. "color: #fff;" +
  646. "cursor: pointer;" +
  647. "text-decoration: none;" +
  648. "text-align: center;" +
  649. "padding-left: 8px;" +
  650. "line-height: 28px;" +
  651. "margin-right:" + margin_right + ";" +
  652. "box-shadow: 0px 0px 4px 0px rgba(98, 98, 98, .8);";
  653. button.innerHTML = text_content;
  654. return button;
  655. }
  656. /*
  657. * Copyright 2015 Google Inc. All Rights Reserved.
  658. * Licensed under the Apache License, Version 2.0 (the "License");
  659. * you may not use this file except in compliance with the License.
  660. * You may obtain a copy of the License at
  661. *
  662. * http://www.apache.org/licenses/LICENSE-2.0
  663. *
  664. * Unless required by applicable law or agreed to in writing, software
  665. * distributed under the License is distributed on an "AS IS" BASIS,
  666. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  667. * See the License for the specific language governing permissions and
  668. * limitations under the License.
  669. */
  670. var DPDB = {"_comment":"AUTOMATICALLY GENERATED BY generate_dpdb.py. DO NOT EDIT.","format":1,"last_updated":"2016-01-26T23:11:18Z","devices":[{"type":"android","rules":[{"mdmh":"asus/*/Nexus 7/*"},{"ua":"Nexus 7"}],"dpi":[320.8,323],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"asus/*/ASUS_Z00AD/*"},{"ua":"ASUS_Z00AD"}],"dpi":[403,404.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC6435LVW/*"},{"ua":"HTC6435LVW"}],"dpi":[449.7,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One XL/*"},{"ua":"HTC One XL"}],"dpi":[315.3,314.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"htc/*/Nexus 9/*"},{"ua":"Nexus 9"}],"dpi":289,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One M9/*"},{"ua":"HTC One M9"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One_M8/*"},{"ua":"HTC One_M8"}],"dpi":[449.7,447.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"HTC/*/HTC One/*"},{"ua":"HTC One"}],"dpi":472.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Huawei/*/Nexus 6P/*"},{"ua":"Nexus 6P"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5X/*"},{"ua":"Nexus 5X"}],"dpi":[422,419.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS345/*"},{"ua":"LGMS345"}],"dpi":[221.7,219.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D800/*"},{"ua":"LG-D800"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/LG-D850/*"},{"ua":"LG-D850"}],"dpi":[537.9,541.9],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"LGE/*/VS985 4G/*"},{"ua":"VS985 4G"}],"dpi":[537.9,535.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 5/*"},{"ua":"Nexus 5 B"}],"dpi":[442.4,444.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/Nexus 4/*"},{"ua":"Nexus 4"}],"dpi":[319.8,318.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LG-P769/*"},{"ua":"LG-P769"}],"dpi":[240.6,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGMS323/*"},{"ua":"LGMS323"}],"dpi":[206.6,204.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"LGE/*/LGLS996/*"},{"ua":"LGLS996"}],"dpi":[403.4,401.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/4560MMX/*"},{"ua":"4560MMX"}],"dpi":[240,219.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/A250/*"},{"ua":"Micromax A250"}],"dpi":[480,446.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Micromax/*/Micromax AQ4501/*"},{"ua":"Micromax AQ4501"}],"dpi":240,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/DROID RAZR/*"},{"ua":"DROID RAZR"}],"dpi":[368.1,256.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT830C/*"},{"ua":"XT830C"}],"dpi":[254,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1021/*"},{"ua":"XT1021"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1023/*"},{"ua":"XT1023"}],"dpi":[254,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1028/*"},{"ua":"XT1028"}],"dpi":[326.6,327.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1034/*"},{"ua":"XT1034"}],"dpi":[326.6,328.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1053/*"},{"ua":"XT1053"}],"dpi":[315.3,316.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1562/*"},{"ua":"XT1562"}],"dpi":[403.4,402.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/Nexus 6/*"},{"ua":"Nexus 6 B"}],"dpi":[494.3,489.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1063/*"},{"ua":"XT1063"}],"dpi":[295,296.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"motorola/*/XT1064/*"},{"ua":"XT1064"}],"dpi":[295,295.6],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1092/*"},{"ua":"XT1092"}],"dpi":[422,424.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"motorola/*/XT1095/*"},{"ua":"XT1095"}],"dpi":[422,423.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/A0001/*"},{"ua":"A0001"}],"dpi":[403.4,401],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE E1005/*"},{"ua":"ONE E1005"}],"dpi":[442.4,441.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OnePlus/*/ONE A2005/*"},{"ua":"ONE A2005"}],"dpi":[391.9,405.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"OPPO/*/X909/*"},{"ua":"X909"}],"dpi":[442.4,444.1],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9082/*"},{"ua":"GT-I9082"}],"dpi":[184.7,185.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G360P/*"},{"ua":"SM-G360P"}],"dpi":[196.7,205.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Nexus S/*"},{"ua":"Nexus S"}],"dpi":[234.5,229.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[304.8,303.9],"bw":5,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T230NU/*"},{"ua":"SM-T230NU"}],"dpi":216,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SGH-T399/*"},{"ua":"SGH-T399"}],"dpi":[217.7,231.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N9005/*"},{"ua":"SM-N9005"}],"dpi":[386.4,387],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SM-N900A/*"},{"ua":"SAMSUNG-SM-N900A"}],"dpi":[386.4,387.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9500/*"},{"ua":"GT-I9500"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9505/*"},{"ua":"GT-I9505"}],"dpi":439.4,"bw":4,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900F/*"},{"ua":"SM-G900F"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G900M/*"},{"ua":"SM-G900M"}],"dpi":[415.6,431.6],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G800F/*"},{"ua":"SM-G800F"}],"dpi":326.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G906S/*"},{"ua":"SM-G906S"}],"dpi":[562.7,572.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300/*"},{"ua":"GT-I9300"}],"dpi":[306.7,304.8],"bw":5,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-T535/*"},{"ua":"SM-T535"}],"dpi":[142.6,136.4],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N920C/*"},{"ua":"SM-N920C"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9300I/*"},{"ua":"GT-I9300I"}],"dpi":[304.8,305.8],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-I9195/*"},{"ua":"GT-I9195"}],"dpi":[249.4,256.7],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-L520/*"},{"ua":"SPH-L520"}],"dpi":[249.4,255.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SAMSUNG-SGH-I717/*"},{"ua":"SAMSUNG-SGH-I717"}],"dpi":285.8,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SPH-D710/*"},{"ua":"SPH-D710"}],"dpi":[217.7,204.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/GT-N7100/*"},{"ua":"GT-N7100"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SCH-I605/*"},{"ua":"SCH-I605"}],"dpi":265.1,"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/Galaxy Nexus/*"},{"ua":"Galaxy Nexus"}],"dpi":[315.3,314.2],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910H/*"},{"ua":"SM-N910H"}],"dpi":[515.1,518],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-N910C/*"},{"ua":"SM-N910C"}],"dpi":[515.2,520.2],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G130M/*"},{"ua":"SM-G130M"}],"dpi":[165.9,164.8],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G928I/*"},{"ua":"SM-G928I"}],"dpi":[515.1,518.4],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920F/*"},{"ua":"SM-G920F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G920P/*"},{"ua":"SM-G920P"}],"dpi":[522.5,577],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925F/*"},{"ua":"SM-G925F"}],"dpi":580.6,"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"samsung/*/SM-G925V/*"},{"ua":"SM-G925V"}],"dpi":[522.5,576.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/C6903/*"},{"ua":"C6903"}],"dpi":[442.5,443.3],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"Sony/*/D6653/*"},{"ua":"D6653"}],"dpi":[428.6,427.6],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6653/*"},{"ua":"E6653"}],"dpi":[428.6,425.7],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/E6853/*"},{"ua":"E6853"}],"dpi":[403.4,401.9],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"Sony/*/SGP321/*"},{"ua":"SGP321"}],"dpi":[224.7,224.1],"bw":3,"ac":500},{"type":"android","rules":[{"mdmh":"TCT/*/ALCATEL ONE TOUCH Fierce/*"},{"ua":"ALCATEL ONE TOUCH Fierce"}],"dpi":[240,247.5],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"THL/*/thl 5000/*"},{"ua":"thl 5000"}],"dpi":[480,443.3],"bw":3,"ac":1000},{"type":"android","rules":[{"mdmh":"ZTE/*/ZTE Blade L2/*"},{"ua":"ZTE Blade L2"}],"dpi":240,"bw":3,"ac":500},{"type":"ios","rules":[{"res":[640,960]}],"dpi":[325.1,328.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[640,1136]}],"dpi":[317.1,320.2],"bw":3,"ac":1000},{"type":"ios","rules":[{"res":[750,1334]}],"dpi":326.4,"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1242,2208]}],"dpi":[453.6,458.4],"bw":4,"ac":1000},{"type":"ios","rules":[{"res":[1125,2001]}],"dpi":[410.9,415.4],"bw":4,"ac":1000}]}
  671. };
  672. var hmd_conf_factory = register("hmd_conf", HMD_config);
  673. export default hmd_conf_factory;