PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/static/scripts/utils/config.js

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