PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/static/scripts/utils/config.js

https://bitbucket.org/kellrott/galaxy-central
JavaScript | 312 lines | 202 code | 39 blank | 71 comment | 30 complexity | ada45cdb46a18215ce9caa792cc730d5 MD5 | raw file
Possible License(s): CC-BY-3.0
  1. define(['libs/underscore', 'viz/trackster/util', 'utils/config'], function(_, util_mod, config_mod) {
  2. /**
  3. * A configuration setting. Currently key is used as id.
  4. */
  5. var ConfigSetting = Backbone.Model.extend({
  6. initialize: function(options) {
  7. // Use key as id for now.
  8. var key = this.get('key');
  9. this.set('id', key);
  10. // Set defaults based on key.
  11. var defaults = _.find(ConfigSetting.known_settings_defaults, function(s) { return s.key === key; });
  12. if (defaults) {
  13. this.set(_.extend({}, defaults, options));
  14. }
  15. if (this.get('value') === undefined) {
  16. // Use default to set value.
  17. this.set_value(this.get('default_value'));
  18. // If no default value for color config, set random color.
  19. if (!this.get('value') && this.get('type') === 'color') {
  20. // For color setting, set random color.
  21. this.set('value', util_mod.get_random_color());
  22. }
  23. }
  24. },
  25. /**
  26. * Cast and set value. This should be instead of
  27. * setting.set('value', new_value)
  28. */
  29. set_value: function(value, options) {
  30. var type = this.get('type');
  31. if (type === 'float') {
  32. value = parseFloat(value);
  33. }
  34. else if (type === 'int') {
  35. value = parseInt(value, 10);
  36. }
  37. // TODO: handle casting from string to bool?
  38. this.set({value: value}, options);
  39. }
  40. }, {
  41. // This is a master list of default settings for known settings.
  42. known_settings_defaults: [
  43. { key: 'name', label: 'Name', type: 'text', default_value: '' },
  44. { key: 'color', label: 'Color', type: 'color', default_value: null },
  45. { key: 'min_value', label: 'Min Value', type: 'float', default_value: null },
  46. { key: 'max_value', label: 'Max Value', type: 'float', default_value: null },
  47. { key: 'mode', type: 'string', default_value: this.mode, hidden: true },
  48. { key: 'height', type: 'int', default_value: 32, hidden: true },
  49. { key: 'pos_color', label: 'Positive Color', type: 'color', default_value: "#FF8C00" },
  50. { key: 'neg_color', label: 'Negative Color', type: 'color', default_value: "#4169E1" },
  51. { key: 'block_color', label: 'Block color', type: 'color', default_value: null },
  52. { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' },
  53. { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false },
  54. { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true },
  55. { key: 'mode', type: 'string', default_value: this.mode, hidden: true },
  56. { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: null },
  57. { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true },
  58. { key: 'mode', type: 'string', default_value: this.mode, hidden: true }
  59. ]
  60. });
  61. /**
  62. * Collection of config settings.
  63. */
  64. var ConfigSettingCollection = Backbone.Collection.extend({
  65. model: ConfigSetting,
  66. /**
  67. * Save settings as a dictionary of key-value pairs.
  68. * This function is needed for backwards compatibility.
  69. */
  70. to_key_value_dict: function() {
  71. var rval = {};
  72. this.each(function(setting) {
  73. rval[setting.get('key')] = setting.get('value');
  74. });
  75. return rval;
  76. },
  77. /**
  78. * Returns value for a given key. Returns undefined if there is no setting with the specified key.
  79. */
  80. get_value: function(key) {
  81. var s = this.get(key);
  82. if (s) {
  83. return s.get('value');
  84. }
  85. return undefined;
  86. },
  87. /**
  88. * Set value for a setting.
  89. */
  90. set_value: function(key, value, options) {
  91. var s = this.get(key);
  92. if (s) {
  93. return s.set_value(value, options);
  94. }
  95. return undefined;
  96. },
  97. /**
  98. * Set default value for a setting.
  99. */
  100. set_default_value: function(key, default_value) {
  101. var s = this.get(key);
  102. if (s) {
  103. return s.set('default_value', default_value);
  104. }
  105. return undefined;
  106. }
  107. },
  108. {
  109. /**
  110. * Utility function that creates a ConfigSettingsCollection from a set of models
  111. * and a saved_values dictionary.
  112. */
  113. from_models_and_saved_values: function(models, saved_values) {
  114. // If there are saved values, copy models and update with saved values.
  115. if (saved_values) {
  116. models = _.map(models, function(m) {
  117. return _.extend({}, m, { value: saved_values[m.key] });
  118. });
  119. }
  120. return new ConfigSettingCollection(models);
  121. }
  122. });
  123. /**
  124. * Viewer for config settings collection.
  125. */
  126. var ConfigSettingCollectionView = Backbone.View.extend({
  127. className: 'config-settings-view',
  128. /**
  129. * Renders form for editing configuration settings.
  130. */
  131. render: function() {
  132. var container = this.$el;
  133. this.collection.each(function(param, index) {
  134. // Hidden params have no representation in the form
  135. if (param.get('hidden')) { return; }
  136. // Build row for param.
  137. var id = 'param_' + index,
  138. type = param.get('type'),
  139. value = param.get('value');
  140. var row = $("<div class='form-row' />").appendTo(container);
  141. row.append($('<label />').attr("for", id ).text(param.get('label') + ":" ));
  142. // Draw parameter as checkbox
  143. if ( type === 'bool' ) {
  144. row.append( $('<input type="checkbox" />').attr("id", id ).attr("name", id ).attr( 'checked', value ) );
  145. }
  146. // Draw parameter as textbox
  147. else if ( type === 'text' ) {
  148. row.append( $('<input type="text"/>').attr("id", id ).val(value).click( function() { $(this).select(); }));
  149. }
  150. // Draw parameter as select area
  151. else if ( type === 'select' ) {
  152. var select = $('<select />').attr("id", id);
  153. _.each(param.get('options'), function(option) {
  154. $("<option/>").text( option.label ).attr( "value", option.value ).appendTo( select );
  155. });
  156. select.val( value );
  157. row.append( select );
  158. }
  159. // Draw parameter as color picker
  160. else if ( type === 'color' ) {
  161. var
  162. container_div = $("<div/>").appendTo(row),
  163. input = $('<input />').attr("id", id ).attr("name", id ).val( value ).css("float", "left")
  164. .appendTo(container_div).click(function(e) {
  165. // Hide other pickers.
  166. $(".tooltip").removeClass( "in" );
  167. // Show input's color picker.
  168. var tip = $(this).siblings(".tooltip").addClass( "in" );
  169. tip.css( {
  170. // left: $(this).position().left + ( $(input).width() / 2 ) - 60,
  171. // top: $(this).position().top + $(this.height)
  172. left: $(this).position().left + $(this).width() + 5,
  173. top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(this).height() / 2 )
  174. } ).show();
  175. // Click management:
  176. // Keep showing tip if clicking in tip.
  177. tip.click(function(e) {
  178. e.stopPropagation();
  179. });
  180. // Hide tip if clicking outside of tip.
  181. $(document).bind( "click.color-picker", function() {
  182. tip.hide();
  183. $(document).unbind( "click.color-picker" );
  184. });
  185. // No propagation to avoid triggering document click (and tip hiding) above.
  186. e.stopPropagation();
  187. }),
  188. // Icon for setting a new random color; behavior set below.
  189. new_color_icon = $("<a href='javascript:void(0)'/>").addClass("icon-button arrow-circle").appendTo(container_div)
  190. .attr("title", "Set new random color").tooltip(),
  191. // Color picker in tool tip style.
  192. tip = $( "<div class='tooltip right' style='position: absolute;' />" ).appendTo(container_div).hide(),
  193. // Inner div for padding purposes
  194. tip_inner = $("<div class='tooltip-inner' style='text-align: inherit'></div>").appendTo(tip),
  195. tip_arrow = $("<div class='tooltip-arrow'></div>").appendTo(tip),
  196. farb_obj = $.farbtastic(tip_inner, { width: 100, height: 100, callback: input, color: value });
  197. // Clear floating.
  198. container_div.append( $("<div/>").css("clear", "both"));
  199. // Use function to fix farb_obj value.
  200. (function(fixed_farb_obj) {
  201. new_color_icon.click(function() {
  202. fixed_farb_obj.setColor(util_mod.get_random_color());
  203. });
  204. })(farb_obj);
  205. }
  206. else {
  207. row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) );
  208. }
  209. // Help text
  210. if ( param.help ) {
  211. row.append( $("<div class='help'/>").text( param.help ) );
  212. }
  213. });
  214. return this;
  215. },
  216. /**
  217. * Render view in modal.
  218. */
  219. render_in_modal: function(title) {
  220. // Set up handlers for cancel, ok button and for handling esc key.
  221. var self = this,
  222. cancel_fn = function() { Galaxy.modal.hide(); $(window).unbind("keypress.check_enter_esc"); },
  223. ok_fn = function() {
  224. Galaxy.modal.hide();
  225. $(window).unbind("keypress.check_enter_esc");
  226. self.update_from_form();
  227. },
  228. check_enter_esc = function(e) {
  229. if ((e.keyCode || e.which) === 27) { // Escape key
  230. cancel_fn();
  231. } else if ((e.keyCode || e.which) === 13) { // Enter key
  232. ok_fn();
  233. }
  234. };
  235. // Set keypress handler.
  236. $(window).bind("keypress.check_enter_esc", check_enter_esc);
  237. // Show modal.
  238. if (this.$el.children().length === 0) {
  239. this.render();
  240. }
  241. Galaxy.modal.show({
  242. title: title || "Configure",
  243. body: this.$el,
  244. buttons: {
  245. "Cancel": cancel_fn,
  246. "OK": ok_fn
  247. }
  248. });
  249. },
  250. /**
  251. * Update settings with new values entered via form.
  252. */
  253. update_from_form: function() {
  254. var self = this;
  255. this.collection.each(function(setting, index) {
  256. if ( !setting.get('hidden') ) {
  257. // Set value from view.
  258. var id = 'param_' + index;
  259. var value = self.$el.find( '#' + id ).val();
  260. if ( setting.get('type') === 'bool' ) {
  261. value = self.$el.find( '#' + id ).is( ':checked' );
  262. }
  263. setting.set_value(value);
  264. }
  265. });
  266. }
  267. });
  268. return {
  269. ConfigSetting: ConfigSetting,
  270. ConfigSettingCollection: ConfigSettingCollection,
  271. ConfigSettingCollectionView: ConfigSettingCollectionView
  272. };
  273. });