You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
679 lines
24 KiB
679 lines
24 KiB
// License: Apache 2.0. See LICENSE file in root directory.
|
|
// Copyright(c) 2022 Intel Corporation. All Rights Reserved.
|
|
|
|
#include "option-model.h"
|
|
#include <librealsense2/rs_advanced_mode.hpp>
|
|
#include <imgui.h>
|
|
#include <imgui_internal.h>
|
|
#include "device-model.h"
|
|
#include "subdevice-model.h"
|
|
|
|
namespace rs2
|
|
{
|
|
option_model create_option_model( option_value const & opt,
|
|
const std::string& opt_base_label,
|
|
subdevice_model* model,
|
|
std::shared_ptr<options> options,
|
|
bool* options_invalidated,
|
|
std::string& error_message)
|
|
{
|
|
option_model option = {};
|
|
|
|
std::string const option_name = options->get_option_name( opt->id );
|
|
option.id = rsutils::string::from() << opt_base_label << '/' << option_name;
|
|
option.opt = opt->id;
|
|
option.endpoint = options;
|
|
option.label = rsutils::string::from() << option_name << "##" << option.id;
|
|
option.invalidate_flag = options_invalidated;
|
|
option.dev = model;
|
|
option.value = opt;
|
|
option.supported = opt->is_valid; // i.e., supported-and-enabled!
|
|
option.range = options->get_option_range( opt->id );
|
|
option.read_only = options->is_option_read_only( opt->id );
|
|
return option;
|
|
}
|
|
}
|
|
|
|
using namespace rs2;
|
|
|
|
std::string option_model::adjust_description(const std::string& str_in, const std::string& to_be_replaced, const std::string& to_replace)
|
|
{
|
|
std::string adjusted_string(str_in);
|
|
auto pos = adjusted_string.find(to_be_replaced);
|
|
adjusted_string.replace(pos, to_be_replaced.size(), to_replace);
|
|
return adjusted_string;
|
|
}
|
|
|
|
bool option_model::draw( std::string & error_message,
|
|
notifications_model & model,
|
|
bool new_line,
|
|
bool use_option_name )
|
|
{
|
|
auto res = false;
|
|
if( endpoint->supports( opt ) )
|
|
{
|
|
// The option's rendering model supports an alternative option title derived from its
|
|
// description rather than name. This is applied to the Holes Filling as its display must
|
|
// conform with the names used by a 3rd-party tools for consistency.
|
|
if( opt == RS2_OPTION_HOLES_FILL )
|
|
use_option_name = false;
|
|
|
|
std::string desc_str( endpoint->get_option_description( opt ) );
|
|
|
|
// Device D405 is for short range, therefore, its units are in cm - for better UX
|
|
bool use_cm_units = false;
|
|
std::string device_pid = dev->dev.get_info( RS2_CAMERA_INFO_PRODUCT_ID );
|
|
if( device_pid == "0B5B"
|
|
&& val_in_range(
|
|
opt,
|
|
{ RS2_OPTION_MIN_DISTANCE, RS2_OPTION_MAX_DISTANCE, RS2_OPTION_DEPTH_UNITS } ) )
|
|
{
|
|
use_cm_units = true;
|
|
desc_str = adjust_description( desc_str, "meters", "cm" );
|
|
}
|
|
|
|
auto desc = desc_str.c_str();
|
|
|
|
// remain option to append to the current line
|
|
if( ! new_line )
|
|
ImGui::SameLine();
|
|
|
|
if( is_enum() )
|
|
{
|
|
res = draw_combobox( model, error_message, desc, new_line, use_option_name );
|
|
}
|
|
else
|
|
{
|
|
if( is_checkbox() )
|
|
{
|
|
res = draw_checkbox( model, error_message, desc );
|
|
}
|
|
else
|
|
{
|
|
res = draw_slider( model, error_message, desc, use_cm_units );
|
|
}
|
|
}
|
|
|
|
if( ! read_only && opt == RS2_OPTION_ENABLE_AUTO_EXPOSURE && dev->auto_exposure_enabled
|
|
&& dev->s->is< roi_sensor >() && dev->streaming )
|
|
{
|
|
ImGui::SameLine( 0, 10 );
|
|
std::string button_label = label;
|
|
auto index = label.find_last_of( '#' );
|
|
if( index != std::string::npos )
|
|
{
|
|
button_label = label.substr( index + 1 );
|
|
}
|
|
|
|
ImGui::PushStyleColor( ImGuiCol_TextSelectedBg, { 1.f, 1.f, 1.f, 1.f } );
|
|
if( ! dev->roi_checked )
|
|
{
|
|
std::string caption = rsutils::string::from() << "Set ROI##" << button_label;
|
|
if( ImGui::Button( caption.c_str(), { 55, 0 } ) )
|
|
{
|
|
dev->roi_checked = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
std::string caption = rsutils::string::from() << "Cancel##" << button_label;
|
|
if( ImGui::Button( caption.c_str(), { 55, 0 } ) )
|
|
{
|
|
dev->roi_checked = false;
|
|
}
|
|
}
|
|
ImGui::PopStyleColor();
|
|
|
|
if( ImGui::IsItemHovered() )
|
|
ImGui::SetTooltip( "Select custom region of interest for the auto-exposure "
|
|
"algorithm\nClick the button, then draw a rect on the frame" );
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
void option_model::update_supported( std::string & error_message )
|
|
{
|
|
try
|
|
{
|
|
supported = endpoint->supports( opt );
|
|
}
|
|
catch( const error & e )
|
|
{
|
|
error_message = error_to_string( e );
|
|
}
|
|
}
|
|
|
|
void option_model::update_read_only_status( std::string & error_message )
|
|
{
|
|
try
|
|
{
|
|
read_only = endpoint->is_option_read_only( opt );
|
|
}
|
|
catch( const error & e )
|
|
{
|
|
error_message = error_to_string( e );
|
|
}
|
|
}
|
|
|
|
void option_model::update_all_fields( std::string & error_message, notifications_model & model )
|
|
{
|
|
try
|
|
{
|
|
value = endpoint->get_option_value( opt );
|
|
supported = value->is_valid;
|
|
if( supported )
|
|
{
|
|
range = endpoint->get_option_range( opt );
|
|
read_only = endpoint->is_option_read_only( opt );
|
|
}
|
|
}
|
|
catch( const error & e )
|
|
{
|
|
if( read_only )
|
|
{
|
|
model.add_notification( { rsutils::string::from()
|
|
<< "Could not refresh read-only option "
|
|
<< endpoint->get_option_name( opt ) << ": " << e.what(),
|
|
RS2_LOG_SEVERITY_WARN,
|
|
RS2_NOTIFICATION_CATEGORY_UNKNOWN_ERROR } );
|
|
}
|
|
else
|
|
error_message = error_to_string( e );
|
|
}
|
|
}
|
|
|
|
bool option_model::is_all_integers() const
|
|
{
|
|
return is_integer( range.min ) && is_integer( range.max ) && is_integer( range.def )
|
|
&& is_integer( range.step );
|
|
}
|
|
|
|
bool option_model::is_enum() const
|
|
{
|
|
// We do not expect enum values to have a step that is smaller than 1,
|
|
// and we don't want to compare a floating point value to an integer so 0.9 will do the work.
|
|
if( range.step < 0.9f )
|
|
return false;
|
|
|
|
for( auto i = range.min; i <= range.max; i += range.step )
|
|
{
|
|
if( endpoint->get_option_value_description( opt, i ) == nullptr )
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
std::vector< const char * > option_model::get_combo_labels( int * p_selected ) const
|
|
{
|
|
int selected = 0, counter = 0;
|
|
std::vector< const char * > labels;
|
|
for( auto i = range.min; i <= range.max; i += range.step, counter++ )
|
|
{
|
|
auto label = endpoint->get_option_value_description( opt, i );
|
|
|
|
switch( value->type )
|
|
{
|
|
case RS2_OPTION_TYPE_FLOAT:
|
|
if( std::fabs( i - value->as_float ) < 0.001f )
|
|
selected = counter;
|
|
break;
|
|
case RS2_OPTION_TYPE_STRING:
|
|
if( 0 == strcmp( label, value->as_string ) )
|
|
selected = counter;
|
|
break;
|
|
}
|
|
|
|
labels.push_back( label );
|
|
}
|
|
if( p_selected )
|
|
*p_selected = selected;
|
|
return labels;
|
|
}
|
|
|
|
bool option_model::draw_combobox( notifications_model & model,
|
|
std::string & error_message,
|
|
const char * description,
|
|
bool new_line,
|
|
bool use_option_name )
|
|
{
|
|
bool item_clicked = false;
|
|
std::string txt = rsutils::string::from()
|
|
<< ( use_option_name ? endpoint->get_option_name( opt ) : description ) << ":";
|
|
|
|
float text_length = ImGui::CalcTextSize( txt.c_str() ).x;
|
|
float combo_position_x = ImGui::GetCursorPosX() + text_length + 5;
|
|
|
|
ImGui::Text( "%s", txt.c_str() );
|
|
if( ImGui::IsItemHovered() && description )
|
|
{
|
|
ImGui::SetTooltip( "%s", description );
|
|
}
|
|
|
|
ImGui::SameLine();
|
|
if( new_line )
|
|
ImGui::SetCursorPosX( combo_position_x );
|
|
|
|
ImGui::PushItemWidth( new_line ? -1.f : 100.f );
|
|
|
|
int selected;
|
|
std::vector< const char * > labels = get_combo_labels( &selected );
|
|
ImGui::PushStyleColor( ImGuiCol_TextSelectedBg, { 1, 1, 1, 1 } );
|
|
|
|
try
|
|
{
|
|
if( ImGui::Combo( id.c_str(), &selected, labels.data(), static_cast< int >( labels.size() ) ) )
|
|
{
|
|
float tmp_value = range.min + range.step * selected;
|
|
model.add_log( rsutils::string::from()
|
|
<< "Setting " << opt << " to " << tmp_value << " (" << labels[selected] << ")" );
|
|
set_option( opt, tmp_value, error_message );
|
|
if( invalidate_flag )
|
|
*invalidate_flag = true;
|
|
item_clicked = true;
|
|
}
|
|
}
|
|
catch( const error & e )
|
|
{
|
|
error_message = error_to_string( e );
|
|
}
|
|
|
|
ImGui::PopStyleColor();
|
|
ImGui::PopItemWidth();
|
|
return item_clicked;
|
|
}
|
|
|
|
bool option_model::draw_slider( notifications_model & model,
|
|
std::string & error_message,
|
|
const char * description,
|
|
bool use_cm_units )
|
|
{
|
|
bool slider_clicked = false;
|
|
std::string txt = rsutils::string::from() << endpoint->get_option_name( opt ) << ":";
|
|
ImGui::Text( "%s", txt.c_str() );
|
|
|
|
ImGui::SameLine();
|
|
ImGui::SetCursorPosX( read_only ? 268.f : 245.f );
|
|
ImGui::PushStyleColor( ImGuiCol_Text, grey );
|
|
ImGui::PushStyleColor( ImGuiCol_TextSelectedBg, grey );
|
|
ImGui::PushStyleColor( ImGuiCol_ButtonActive, { 1.f, 1.f, 1.f, 0.f } );
|
|
ImGui::PushStyleColor( ImGuiCol_ButtonHovered, { 1.f, 1.f, 1.f, 0.f } );
|
|
ImGui::PushStyleColor( ImGuiCol_Button, { 1.f, 1.f, 1.f, 0.f } );
|
|
ImGui::Button( textual_icons::question_mark, { 20, 20 } );
|
|
ImGui::PopStyleColor( 5 );
|
|
if( ImGui::IsItemHovered() && description )
|
|
{
|
|
ImGui::SetTooltip( "%s", description );
|
|
}
|
|
|
|
if( ! read_only )
|
|
{
|
|
ImGui::SameLine();
|
|
ImGui::SetCursorPosX( 268 );
|
|
if( ! edit_mode )
|
|
{
|
|
std::string edit_id = rsutils::string::from() << textual_icons::edit << "##" << id;
|
|
ImGui::PushStyleColor( ImGuiCol_Text, light_grey );
|
|
ImGui::PushStyleColor( ImGuiCol_TextSelectedBg, light_grey );
|
|
ImGui::PushStyleColor( ImGuiCol_ButtonHovered, { 1.f, 1.f, 1.f, 0.f } );
|
|
ImGui::PushStyleColor( ImGuiCol_Button, { 1.f, 1.f, 1.f, 0.f } );
|
|
if( ImGui::Button( edit_id.c_str(), { 20, 20 } ) )
|
|
{
|
|
if( is_all_integers() )
|
|
edit_value = rsutils::string::from() << (int)value->as_float;
|
|
else
|
|
edit_value = rsutils::string::from() << value->as_float;
|
|
edit_mode = true;
|
|
}
|
|
if( ImGui::IsItemHovered() )
|
|
{
|
|
ImGui::SetTooltip( "Enter text-edit mode" );
|
|
}
|
|
ImGui::PopStyleColor( 4 );
|
|
}
|
|
else
|
|
{
|
|
std::string edit_id = rsutils::string::from() << textual_icons::edit << "##" << id;
|
|
ImGui::PushStyleColor( ImGuiCol_Text, light_blue );
|
|
ImGui::PushStyleColor( ImGuiCol_TextSelectedBg, light_blue );
|
|
ImGui::PushStyleColor( ImGuiCol_ButtonHovered, { 1.f, 1.f, 1.f, 0.f } );
|
|
ImGui::PushStyleColor( ImGuiCol_Button, { 1.f, 1.f, 1.f, 0.f } );
|
|
if( ImGui::Button( edit_id.c_str(), { 20, 20 } ) )
|
|
{
|
|
edit_mode = false;
|
|
}
|
|
if( ImGui::IsItemHovered() )
|
|
{
|
|
ImGui::SetTooltip( "Exit text-edit mode" );
|
|
}
|
|
ImGui::PopStyleColor( 4 );
|
|
}
|
|
}
|
|
|
|
ImGui::PushItemWidth( -1 );
|
|
|
|
try
|
|
{
|
|
if( read_only )
|
|
{
|
|
ImVec2 vec{ 0, 20 };
|
|
std::string text = ( value->as_float == (int)value->as_float ) ? std::to_string( (int)value->as_float )
|
|
: std::to_string( value->as_float );
|
|
if( range.min != range.max )
|
|
{
|
|
ImGui::ProgressBar( ( value->as_float / ( range.max - range.min ) ), vec, text.c_str() );
|
|
}
|
|
else // constant value options
|
|
{
|
|
auto c = ImGui::ColorConvertU32ToFloat4( ImGui::GetColorU32( ImGuiCol_FrameBg ) );
|
|
ImGui::PushStyleColor( ImGuiCol_FrameBgActive, c );
|
|
ImGui::PushStyleColor( ImGuiCol_FrameBgHovered, c );
|
|
float dummy = std::floor( value->as_float );
|
|
if( ImGui::DragFloat( id.c_str(), &dummy, 1, 0, 0, text.c_str() ) )
|
|
{
|
|
// Changing the depth units not on advanced mode is not allowed,
|
|
// prompt the user to switch to advanced mode for chaging it.
|
|
if( RS2_OPTION_DEPTH_UNITS == opt )
|
|
{
|
|
auto advanced = dev->dev.as< rs400::advanced_mode >();
|
|
if( advanced )
|
|
if( ! advanced.is_enabled() )
|
|
dev->draw_advanced_mode_prompt = true;
|
|
}
|
|
}
|
|
ImGui::PopStyleColor( 2 );
|
|
}
|
|
}
|
|
else if( edit_mode )
|
|
{
|
|
std::string buff_str = edit_value;
|
|
|
|
// lambda function used to convert meters to cm - while the number is a string
|
|
auto convert_float_str = []( std::string float_str, float conversion_factor ) {
|
|
if( float_str.size() == 0 )
|
|
return float_str;
|
|
float number_float = std::stof( float_str );
|
|
return std::to_string( number_float * conversion_factor );
|
|
};
|
|
|
|
// when cm must be used instead of meters
|
|
if( use_cm_units )
|
|
buff_str = convert_float_str( buff_str, 100.f );
|
|
|
|
char buff[TEXT_BUFF_SIZE];
|
|
memset( buff, 0, TEXT_BUFF_SIZE );
|
|
strcpy( buff, buff_str.c_str() );
|
|
|
|
if( ImGui::InputText( id.c_str(),
|
|
buff,
|
|
TEXT_BUFF_SIZE,
|
|
ImGuiInputTextFlags_EnterReturnsTrue ) )
|
|
{
|
|
if( use_cm_units )
|
|
{
|
|
buff_str = convert_float_str( std::string( buff ), 0.01f );
|
|
memset( buff, 0, TEXT_BUFF_SIZE );
|
|
strcpy( buff, buff_str.c_str() );
|
|
}
|
|
float new_value;
|
|
if( ! rsutils::string::string_to_value< float >( buff, new_value ) )
|
|
{
|
|
error_message = "Invalid float input!";
|
|
}
|
|
else if( new_value < range.min || new_value > range.max )
|
|
{
|
|
float val = use_cm_units ? new_value * 100.f : new_value;
|
|
float min = use_cm_units ? range.min * 100.f : range.min;
|
|
float max = use_cm_units ? range.max * 100.f : range.max;
|
|
|
|
error_message = rsutils::string::from()
|
|
<< val << " is out of bounds [" << min << ", " << max << "]";
|
|
}
|
|
else
|
|
{
|
|
// run when the value is valid and the enter key is pressed to submit the new value
|
|
auto option_was_set = set_option(opt, new_value, error_message);
|
|
if (option_was_set)
|
|
{
|
|
if (invalidate_flag)
|
|
*invalidate_flag = true;
|
|
model.add_log(rsutils::string::from() << "Setting " << opt << " to " << value->as_float);
|
|
}
|
|
}
|
|
edit_mode = false;
|
|
}
|
|
else if( use_cm_units )
|
|
{
|
|
buff_str = convert_float_str( buff_str, 0.01f );
|
|
memset( buff, 0, TEXT_BUFF_SIZE );
|
|
strcpy( buff, buff_str.c_str() );
|
|
}
|
|
edit_value = buff;
|
|
}
|
|
else if( is_all_integers() )
|
|
{
|
|
// runs when changing a value with slider and not the textbox
|
|
auto int_value = static_cast< int >( value->as_float );
|
|
|
|
if( ImGui::SliderIntWithSteps( id.c_str(),
|
|
&int_value,
|
|
static_cast< int >( range.min ),
|
|
static_cast< int >( range.max ),
|
|
static_cast< int >( range.step ) ) )
|
|
{
|
|
// TODO: Round to step?
|
|
slider_clicked = slider_selected( opt,
|
|
static_cast< float >( int_value ),
|
|
error_message,
|
|
model );
|
|
}
|
|
else
|
|
{
|
|
slider_clicked = slider_unselected( opt,
|
|
static_cast< float >( int_value ),
|
|
error_message,
|
|
model );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
float tmp_value = value->as_float;
|
|
float temp_value_displayed = tmp_value;
|
|
float min_range_displayed = range.min;
|
|
float max_range_displayed = range.max;
|
|
|
|
// computing the number of decimal digits taken from the step options' property
|
|
// this will then be used to format the displayed value
|
|
auto num_of_decimal_digits = []( float f ) {
|
|
float f_0 = std::fabs( f - (int)f );
|
|
std::string s = std::to_string( f_0 );
|
|
size_t cur_len = s.length();
|
|
// removing trailing zeros
|
|
while( cur_len > 3 && s[cur_len - 1] == '0' )
|
|
cur_len--;
|
|
return cur_len - 2;
|
|
};
|
|
int num_of_decimal_digits_displayed = (int)num_of_decimal_digits( range.step );
|
|
|
|
// displaying in cm instead of meters for D405
|
|
if( use_cm_units )
|
|
{
|
|
temp_value_displayed *= 100.f;
|
|
min_range_displayed *= 100.f;
|
|
max_range_displayed *= 100.f;
|
|
int updated_num_of_decimal_digits_displayed = num_of_decimal_digits_displayed - 2;
|
|
if( updated_num_of_decimal_digits_displayed > 0 )
|
|
num_of_decimal_digits_displayed = updated_num_of_decimal_digits_displayed;
|
|
}
|
|
|
|
std::stringstream formatting_ss;
|
|
formatting_ss << "%." << num_of_decimal_digits_displayed << "f";
|
|
|
|
|
|
if( ImGui::SliderFloat( id.c_str(),
|
|
&temp_value_displayed,
|
|
min_range_displayed,
|
|
max_range_displayed,
|
|
formatting_ss.str().c_str() ) )
|
|
{
|
|
tmp_value = use_cm_units ? temp_value_displayed / 100.f : temp_value_displayed;
|
|
auto loffset = std::abs( fmod( tmp_value, range.step ) );
|
|
auto roffset = range.step - loffset;
|
|
if( tmp_value >= 0 )
|
|
tmp_value = ( loffset < roffset ) ? tmp_value - loffset : tmp_value + roffset;
|
|
else
|
|
tmp_value = ( loffset < roffset ) ? tmp_value + loffset : tmp_value - roffset;
|
|
tmp_value = ( tmp_value < range.min ) ? range.min : tmp_value;
|
|
tmp_value = ( tmp_value > range.max ) ? range.max : tmp_value;
|
|
|
|
slider_clicked = slider_selected( opt, tmp_value, error_message, model );
|
|
}
|
|
else
|
|
{
|
|
slider_clicked = slider_unselected( opt, tmp_value, error_message, model );
|
|
}
|
|
}
|
|
}
|
|
catch( const error & e )
|
|
{
|
|
error_message = error_to_string( e );
|
|
}
|
|
|
|
return slider_clicked;
|
|
}
|
|
|
|
bool option_model::is_checkbox() const
|
|
{
|
|
return range.max == 1.0f && range.min == 0.0f && range.step == 1.0f;
|
|
}
|
|
|
|
bool option_model::draw_checkbox( notifications_model & model,
|
|
std::string & error_message,
|
|
const char * description )
|
|
{
|
|
bool checkbox_was_clicked = false;
|
|
|
|
auto bool_value = value->as_float > 0.0f;
|
|
if( ImGui::Checkbox( label.c_str(), &bool_value ) )
|
|
{
|
|
checkbox_was_clicked = true;
|
|
model.add_log( rsutils::string::from() << "Setting " << opt << " to " << ( bool_value ? "1.0" : "0.0" ) << " ("
|
|
<< ( bool_value ? "ON" : "OFF" ) << ")" );
|
|
|
|
set_option( opt, bool_value ? 1.f : 0.f, error_message );
|
|
if (invalidate_flag)
|
|
*invalidate_flag = true;
|
|
}
|
|
if( ImGui::IsItemHovered() && description )
|
|
{
|
|
ImGui::SetTooltip( "%s", description );
|
|
}
|
|
return checkbox_was_clicked;
|
|
}
|
|
|
|
bool option_model::slider_selected( rs2_option opt,
|
|
float value,
|
|
std::string & error_message,
|
|
notifications_model & model )
|
|
{
|
|
bool res = false;
|
|
auto option_was_set = set_option( opt, value, error_message, std::chrono::milliseconds( 200 ) );
|
|
if( option_was_set )
|
|
{
|
|
have_unset_value = false;
|
|
if (invalidate_flag)
|
|
*invalidate_flag = true;
|
|
model.add_log( rsutils::string::from() << "Setting " << opt << " to " << value );
|
|
res = true;
|
|
}
|
|
else
|
|
{
|
|
have_unset_value = true;
|
|
unset_value = value;
|
|
}
|
|
return res;
|
|
}
|
|
bool option_model::slider_unselected( rs2_option opt,
|
|
float value,
|
|
std::string & error_message,
|
|
notifications_model & model )
|
|
{
|
|
bool res = false;
|
|
// Slider unselected, if last value was ignored, set with last value if the value was
|
|
// changed.
|
|
if( have_unset_value )
|
|
{
|
|
if( value != unset_value )
|
|
{
|
|
auto set_ok
|
|
= set_option( opt, unset_value, error_message, std::chrono::milliseconds( 100 ) );
|
|
if( set_ok )
|
|
{
|
|
model.add_log( rsutils::string::from() << "Setting " << opt << " to " << unset_value );
|
|
if (invalidate_flag)
|
|
*invalidate_flag = true;
|
|
have_unset_value = false;
|
|
res = true;
|
|
}
|
|
}
|
|
else
|
|
have_unset_value = false;
|
|
}
|
|
return res;
|
|
}
|
|
|
|
bool option_model::draw_option(bool update_read_only_options,
|
|
bool is_streaming,
|
|
std::string& error_message, notifications_model& model)
|
|
{
|
|
if (update_read_only_options)
|
|
{
|
|
update_supported(error_message);
|
|
if (supported && is_streaming)
|
|
{
|
|
update_read_only_status(error_message);
|
|
if (read_only)
|
|
{
|
|
update_all_fields(error_message, model);
|
|
}
|
|
}
|
|
}
|
|
if (custom_draw_method)
|
|
return custom_draw_method(*this, error_message, model);
|
|
else
|
|
return draw(error_message, model);
|
|
}
|
|
|
|
bool option_model::set_option(rs2_option opt,
|
|
float req_value,
|
|
std::string& error_message,
|
|
std::chrono::steady_clock::duration ignore_period)
|
|
{
|
|
// Only set the value if `ignore_period` time past since last set_option() call for this option
|
|
if (last_set_stopwatch.get_elapsed() < ignore_period)
|
|
return false;
|
|
|
|
try
|
|
{
|
|
last_set_stopwatch.reset();
|
|
endpoint->set_option(opt, req_value);
|
|
}
|
|
catch (const error& e)
|
|
{
|
|
error_message = error_to_string(e);
|
|
}
|
|
|
|
// Only update the cached value once set_option is done! That way, if it doesn't change
|
|
// anything...
|
|
try
|
|
{
|
|
value = endpoint->get_option_value(opt);
|
|
}
|
|
catch (...)
|
|
{
|
|
}
|
|
|
|
return true;
|
|
}
|