PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/static/scripts/utils/config.js

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