Skip to content

Commit

Permalink
Merge pull request #244 from BallAerospace/improve_intchooser_and_flo…
Browse files Browse the repository at this point in the history
…atchooser

closes #235. Improve IntChooser and FloatChooser validation
  • Loading branch information
ryanmelt committed Dec 29, 2015
2 parents 172cf79 + 90f319a commit efe6e6f
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 110 deletions.
89 changes: 36 additions & 53 deletions lib/cosmos/gui/choosers/float_chooser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,57 @@
# attribution addendums as found in the LICENSE.txt

require 'cosmos'
require 'cosmos/gui/choosers/value_chooser'

module Cosmos

class FloatChooser < Qt::Widget
class FloatChooserDoubleValidator < Qt::DoubleValidator
def initialize(*args)
super(*args)
end

def fixup(input)
begin
value = input.to_f
if value < bottom()
# Handle less than bottom
parent().setText(bottom().to_s)
elsif value > top()
# Handle greater than top
parent().setText(top().to_s)
end
rescue Exception => err
# Oh well no fixup
end
end
end

class FloatChooser < ValueChooser
# Callback for a new value entered into the text field
attr_accessor :sel_command_callback

def initialize(
parent, label_text, initial_value,
minimum_value = nil, maximum_value = nil, field_width = 20, fill = false
)
super(parent)
def initialize(parent, label_text, initial_value,
minimum_value = nil, maximum_value = nil,
field_width = 20, fill = false)
super(parent, label_text, initial_value, field_width, fill)
@minimum_value = minimum_value
@maximum_value = maximum_value
@field_width = field_width

layout = Qt::HBoxLayout.new(self)
layout.setContentsMargins(0,0,0,0)

@float_label = Qt::Label.new(label_text)
@float_label.setSizePolicy(Qt::SizePolicy::Fixed, Qt::SizePolicy::Fixed) if fill
layout.addWidget(@float_label)
layout.addStretch unless fill
@float_value = Qt::LineEdit.new(initial_value.to_s)
@float_value.setMinimumWidth(field_width)
if minimum_value or maximum_value
validator = Qt::DoubleValidator.new(@float_value)
validator.setBottom(minimum_value) if minimum_value
validator.setTop(maximum_value) if maximum_value
validator.setNotation(Qt::DoubleValidator::StandardNotation)
@float_value.setValidator(validator)
end
@callback_in_progress = false
@float_value.connect(SIGNAL('editingFinished()')) do
unless @callback_in_progress # Prevent double fire on loss of focus
begin
@callback_in_progress = true
@sel_command_callback.call(string(), value()) if @sel_command_callback
ensure
@callback_in_progress = false
end
end
end
layout.addWidget(@float_value)
setLayout(layout)

@sel_command_callback = nil
end

# Returns the value as a string
def string
@float_value.text
validator = FloatChooserDoubleValidator.new(@value)
validator.setBottom(minimum_value) if minimum_value
validator.setTop(maximum_value) if maximum_value
validator.setNotation(Qt::DoubleValidator::StandardNotation)
@value.setValidator(validator)
end

# Returns the value as a float
def value
float_value = @float_value.text.to_f
float_value = @minimum_value if @minimum_value and float_value < @minimum_value
float_value = @maximum_value if @maximum_value and float_value > @maximum_value
float_value = @value.text.to_f
float_value = @minimum_value if @minimum_value && float_value < @minimum_value
float_value = @maximum_value if @maximum_value && float_value > @maximum_value
float_value
end

# Sets the value of the text field
def value=(new_value)
@float_value.setText(new_value.to_s)
end

end # class FloatChooser
end
end

end # module Cosmos
89 changes: 38 additions & 51 deletions lib/cosmos/gui/choosers/integer_chooser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,72 +9,59 @@
# attribution addendums as found in the LICENSE.txt

require 'cosmos'
require 'cosmos/gui/choosers/value_chooser'

module Cosmos

class IntegerChooser < Qt::Widget
class IntegerChooserIntValidator < Qt::IntValidator
def initialize(*args)
super(*args)
end

def fixup(input)
begin
value = input.to_i
if value < bottom()
# Handle less than bottom
parent().setText(bottom().to_s)
elsif value > top()
# Handle greater than top
parent().setText(top().to_s)
elsif input != value.to_s
# Handle poorly formatted (only known case is float given as starting value)
parent().setText(value.to_s)
end
rescue Exception => err
# Oh well no fixup
end
end
end

class IntegerChooser < ValueChooser
# Callback called when the value changes
attr_accessor :sel_command_callback

def initialize(
parent, label_text, initial_value,
minimum_value = nil, maximum_value = nil, field_width = 20, fill = false
)
super(parent)
def initialize(parent, label_text, initial_value,
minimum_value = nil, maximum_value = nil,
field_width = 20, fill = false)
super(parent, label_text, initial_value, field_width, fill)
@minimum_value = minimum_value
@maximum_value = maximum_value

layout = Qt::HBoxLayout.new(self)
layout.setContentsMargins(0,0,0,0)

@integer_label = Qt::Label.new(label_text)
@integer_label.setSizePolicy(Qt::SizePolicy::Fixed, Qt::SizePolicy::Fixed) if fill
layout.addWidget(@integer_label)
layout.addStretch() unless fill
@integer_value = Qt::LineEdit.new(initial_value.to_s)
@integer_value.setMinimumWidth(field_width)
if minimum_value or maximum_value
validator = Qt::IntValidator.new(@integer_value)
validator.setBottom(minimum_value) if minimum_value
validator.setTop(maximum_value) if maximum_value
@integer_value.setValidator(validator)
end
@callback_in_progress = false
@integer_value.connect(SIGNAL('editingFinished()')) do
unless @callback_in_progress # Prevent double fire on loss of focus
begin
@callback_in_progress = true
@sel_command_callback.call(string(), value()) if @sel_command_callback
ensure
@callback_in_progress = false
end
end
end
layout.addWidget(@integer_value)
setLayout(layout)

@sel_command_callback = nil
end

# Returns the value as a string
def string
@integer_value.text
validator = IntegerChooserIntValidator.new(@value)
validator.setBottom(minimum_value) if minimum_value
validator.setTop(maximum_value) if maximum_value
@value.setValidator(validator)
end

# Returns the value as an integer
def value
integer_value = @integer_value.text.to_i
integer_value = @minimum_value if @minimum_value and integer_value < @minimum_value
integer_value = @maximum_value if @maximum_value and integer_value > @maximum_value
integer_value = @value.text.to_i
integer_value = @minimum_value if @minimum_value && integer_value < @minimum_value
integer_value = @maximum_value if @maximum_value && integer_value > @maximum_value
integer_value
end

# Sets the value
def value=(new_value)
@integer_value.setText(new_value.to_s)
end

end # class IntegerChooser
end
end

end # module Cosmos
67 changes: 67 additions & 0 deletions lib/cosmos/gui/choosers/value_chooser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# encoding: ascii-8bit

# Copyright 2014 Ball Aerospace & Technologies Corp.
# All Rights Reserved.
#
# This program is free software; you can modify and/or redistribute it
# under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 3 with
# attribution addendums as found in the LICENSE.txt

require 'cosmos'

module Cosmos

class ValueChooser < Qt::Widget

# Callback for a new value entered into the text field
attr_accessor :sel_command_callback

def initialize(parent, label_text, initial_value, field_width = 20, fill = false)
super(parent)
@field_width = field_width

layout = Qt::HBoxLayout.new(self)
layout.setContentsMargins(0,0,0,0)

@label = Qt::Label.new(label_text)
@label.setSizePolicy(Qt::SizePolicy::Fixed, Qt::SizePolicy::Fixed) if fill
layout.addWidget(@label)
layout.addStretch unless fill
@value = Qt::LineEdit.new(initial_value.to_s)
@value.setMinimumWidth(field_width)
@callback_in_progress = false
@value.connect(SIGNAL('editingFinished()')) do
unless @callback_in_progress # Prevent double fire on loss of focus
begin
@callback_in_progress = true
@sel_command_callback.call(string(), value()) if @sel_command_callback
ensure
@callback_in_progress = false
end
end
end
layout.addWidget(@value)
setLayout(layout)

@sel_command_callback = nil
end

# Returns the value as a string
def string
@value.text
end

# Returns the value as a string
def value
string()
end

# Sets the value of the text field
def value=(new_value)
@value.setText(new_value.to_s)
end

end
end

Original file line number Diff line number Diff line change
Expand Up @@ -886,11 +886,9 @@ def get_random_color

# Builds the left frame of the tool
def build_left_frame
# Frame around everything
@tabbed_plots_left_frame = Qt::VBoxLayout.new
@left_frame.addLayout(@tabbed_plots_left_frame)

# Seconds Plotted
@seconds_plotted = FloatChooser.new(self,
'Seconds Plotted:',
@tabbed_plots_config.seconds_plotted,
Expand All @@ -900,12 +898,15 @@ def build_left_frame
@seconds_plotted.sel_command_callback = method(:handle_seconds_plotted_change)
@tabbed_plots_left_frame.addWidget(@seconds_plotted)

# Points Saved
@points_saved = IntegerChooser.new(self, 'Points Saved:', @tabbed_plots_config.points_saved, 1, nil, 15)
@points_saved = IntegerChooser.new(self,
'Points Saved:',
@tabbed_plots_config.points_saved,
1,
nil,
15)
@points_saved.sel_command_callback = method(:handle_points_saved_change)
@tabbed_plots_left_frame.addWidget(@points_saved)

# Points Plotted
@points_plotted = IntegerChooser.new(self,
'Points Plotted:',
@tabbed_plots_config.points_plotted,
Expand All @@ -915,7 +916,6 @@ def build_left_frame
@points_plotted.sel_command_callback = method(:handle_points_plotted_change)
@tabbed_plots_left_frame.addWidget(@points_plotted)

# Refresh Rate Hz
@refresh_rate_hz = FloatChooser.new(self,
'Refresh Rate Hz:',
@tabbed_plots_config.refresh_rate_hz,
Expand Down

0 comments on commit efe6e6f

Please sign in to comment.