-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PR #7781 from Nir: Wrap Viewer/DQT error pop up text
- Loading branch information
Showing
8 changed files
with
345 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
#include <string> | ||
#include <vector> | ||
#include <sstream> | ||
#include "wrap.h" | ||
#include "../common/utilities/string/split.h" | ||
#include "../third-party/imgui/imgui.h" | ||
|
||
namespace utilities { | ||
namespace imgui { | ||
|
||
void trim_leading_spaces( std::string &remaining_paragraph ) | ||
{ | ||
auto non_space_index = remaining_paragraph.find_first_not_of( ' ' ); | ||
|
||
if( non_space_index != std::string::npos ) | ||
{ | ||
// Remove trailing spaces | ||
remaining_paragraph = remaining_paragraph.substr( non_space_index ); | ||
} | ||
} | ||
|
||
std::string wrap_paragraph( const std::string & paragraph, int wrap_pixels_width ) | ||
{ | ||
float space_width = ImGui::CalcTextSize( " " ).x; // Calculate space width in pixels | ||
std::string wrapped_line; // The line that is wrapped in this iteration | ||
std::string wrapped_paragraph; // The output wrapped paragraph | ||
auto remaining_paragraph | ||
= paragraph; // Holds the remaining unwrapped part of the input paragraph | ||
|
||
// Handle a case when the paragraph starts with spaces | ||
trim_leading_spaces(remaining_paragraph); | ||
|
||
auto next_word = remaining_paragraph.substr( | ||
0, | ||
remaining_paragraph.find( ' ' ) ); // The next word to add to the current line | ||
bool first_word = true; | ||
|
||
while( ! next_word.empty() ) | ||
{ | ||
float next_x = 0.0f; | ||
// If this is the first word we try to place it first in line, | ||
// if not we concatenate it to the last word after adding a space | ||
if( ! first_word ) | ||
{ | ||
next_x = ImGui::CalcTextSize( wrapped_line.c_str() ).x + space_width; | ||
} | ||
|
||
if( next_x + ImGui::CalcTextSize( next_word.c_str() ).x <= wrap_pixels_width ) | ||
{ | ||
if( ! first_word ) | ||
wrapped_line += " "; // First word should not start with " " | ||
wrapped_line += next_word; | ||
} | ||
else | ||
{ // Current line cannot feat new word so we wrap the line and | ||
// start building the new line | ||
|
||
wrapped_paragraph += wrapped_line; // copy line build by now | ||
if( ! first_word ) | ||
wrapped_paragraph += '\n'; // break the previous line if exist | ||
wrapped_line = next_word; // add next work to new line | ||
} | ||
|
||
first_word = false; | ||
|
||
// If we have more characters left other then the current word, prepare inputs for next | ||
// iteration, If not add the current line built so far to the output and finish current | ||
// line wrap. | ||
if( remaining_paragraph.size() > next_word.size() ) | ||
{ | ||
remaining_paragraph = remaining_paragraph.substr( next_word.size() + 1 ); | ||
|
||
// Handle a case when the paragraph starts with spaces | ||
trim_leading_spaces(remaining_paragraph); | ||
|
||
next_word = remaining_paragraph.substr( 0, remaining_paragraph.find( ' ' ) ); | ||
|
||
// If no more words exist, copy the current wrapped line to output and stop | ||
if( next_word.empty() ) | ||
{ | ||
wrapped_paragraph += wrapped_line; | ||
break; | ||
} | ||
} | ||
else | ||
{ | ||
wrapped_paragraph += wrapped_line; | ||
break; | ||
} | ||
} | ||
|
||
return wrapped_paragraph; | ||
} | ||
|
||
std::string wrap( const std::string & text, int wrap_pixels_width ) | ||
{ | ||
// Do not wrap if the wrap is smaller then 32 pixels (~2 characters on font 16) | ||
if( wrap_pixels_width < 32 ) | ||
return text; | ||
|
||
// Split text into paragraphs | ||
auto paragraphs_vector = string::split( text, '\n' ); | ||
|
||
std::string wrapped_text; | ||
size_t line_number = 1; | ||
// Wrap each line according to the requested wrap width | ||
for( auto paragraph : paragraphs_vector ) | ||
{ | ||
wrapped_text += wrap_paragraph( paragraph, wrap_pixels_width ); | ||
// Each paragraph except the last one ends with a new line | ||
if( line_number++ != paragraphs_vector.size() ) | ||
wrapped_text += '\n'; | ||
} | ||
|
||
return wrapped_text; | ||
} | ||
|
||
} // namespace imgui | ||
} // namespace utilities |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
#pragma once | ||
|
||
namespace utilities { | ||
namespace imgui { | ||
|
||
// Wrap text according to input width | ||
// - Input: - text as a string | ||
// - wrapping width | ||
// - Output: - on success - wrapped text | ||
// - on failure - an empty string | ||
// Example: | ||
// Input: | ||
// this is the first line\nthis is the second line\nthis is the last line , wrap_width = 150 [pixels] | ||
// Output: | ||
// this is the\nfirst line\nthis is the\nsecond line\nthis is the last\nline | ||
// Note: If the paragraph contain multiple spaces, it will be trimmed into a single space. | ||
std::string wrap( const std::string & text, int wrap_pixels_width ); | ||
|
||
} // namespace imgui | ||
} // namespace utilities |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
#include <sstream> | ||
|
||
namespace utilities { | ||
namespace string { | ||
|
||
|
||
// Split input text to vector of strings according to input delimiter | ||
// - Input: string to be split | ||
// - delimiter | ||
// - Output: a vector of strings | ||
// Example: | ||
// Input: | ||
// Text: This is the first line\nThis is the second line\nThis is the last line | ||
// Delimiter : '\n' | ||
// Output: | ||
// [0] this is the first line | ||
// [1] this is the second line | ||
// [2] this is the last line | ||
inline std::vector< std::string > split( const std::string & str , char delimiter) | ||
{ | ||
auto result = std::vector< std::string >{}; | ||
auto ss = std::stringstream{ str }; | ||
|
||
for( std::string line; std::getline( ss, line, delimiter); ) | ||
result.push_back( line ); | ||
|
||
return result; | ||
} | ||
|
||
} // namespace string | ||
} // namespace utilities |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
#define CATCH_CONFIG_MAIN | ||
|
||
#include "../../catch.h" | ||
|
||
#include <easylogging++.h> | ||
#ifdef BUILD_SHARED_LIBS | ||
// With static linkage, ELPP is initialized by librealsense, so doing it here will | ||
// create errors. When we're using the shared .so/.dll, the two are separate and we have | ||
// to initialize ours if we want to use the APIs! | ||
INITIALIZE_EASYLOGGINGPP | ||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
//#cmake:add-file ../../../common/utilities/imgui/wrap.h | ||
//#cmake:add-file ../../../common/utilities/imgui/wrap.cpp | ||
//#cmake:add-file ../../../third-party/imgui/imgui.h | ||
|
||
#include "common.h" | ||
#include "../../../common/utilities/imgui/wrap.h" | ||
#include "../../../third-party/imgui/imgui.h" | ||
|
||
namespace ImGui { | ||
// Mock ImGui function for test | ||
// all characters are at length of 10 pixels except 'i' and 'j' which is 5 pixels | ||
ImVec2 CalcTextSize( const char * text, | ||
const char * text_end, | ||
bool hide_text_after_double_hash, | ||
float wrap_width ) | ||
{ | ||
if (!text) return ImVec2(0.0f, 0.0f); | ||
|
||
float total_size = 0.0f; | ||
while( *text ) | ||
{ | ||
if( *text == 'i' || *text == 'j' ) | ||
total_size += 5.0f; | ||
else | ||
total_size += 10.0f; | ||
text++; | ||
} | ||
return ImVec2( total_size, 0.0f ); | ||
} | ||
} // namespace ImGui | ||
|
||
using namespace utilities::imgui; | ||
|
||
TEST_CASE( "wrap-text", "[string]" ) | ||
{ | ||
// Verify illegal inputs return empty string | ||
CHECK( wrap( "", 0 ) == "" ); | ||
CHECK( wrap( "", 10 ) == "" ); | ||
CHECK( wrap( "abc", 0 ) == "abc" ); | ||
CHECK( wrap( "abc", 10 ) == "abc" ); | ||
CHECK( wrap( "abc\nabc", 0 ) == "abc\nabc" ); | ||
CHECK( wrap( "abc abc", 5 ) == "abc abc" ); | ||
CHECK( wrap( "", 10 ) == "" ); | ||
|
||
// Verify no wrap if not needed | ||
CHECK( wrap( "abc", 100 ) == "abc" ); | ||
CHECK( wrap( "abc\nabc", 100 ) == "abc\nabc" ); | ||
CHECK( wrap( "abc abc a", 100 ) == "abc abc a" ); | ||
|
||
// No wrapping possible, copy line until first space and continue wrapping | ||
CHECK( wrap( "abcdefgh", 40 ) == "abcdefgh" ); | ||
CHECK( wrap( "aabbccddff das ds fr", 50 ) == "aabbccddff\ndas\nds fr" ); | ||
CHECK( wrap( "das aabbccddff ds fr", 50 ) == "das\naabbccddff\nds fr" ); | ||
|
||
// Exact wrap position test | ||
CHECK( wrap( "abcde abcde", 50 ) == "abcde\nabcde" ); | ||
|
||
// Short letters test | ||
CHECK(wrap("aaaa bbbb cc", 100) == "aaaa bbbb\ncc"); | ||
// i and j are only 5 pixels so we get more characters inside the wrap | ||
CHECK(wrap("aaaa iijj cc", 100) == "aaaa iijj cc"); | ||
|
||
|
||
// Check wrapping of 3 paragraphs | ||
CHECK( wrap( "this is the first line\nthis is the second line\nthis is the last line", 150 ) | ||
== "this is the\nfirst line\nthis is the\nsecond line\nthis is the last\nline" ); | ||
|
||
CHECK( wrap( "this is the first line\nthis is the second line\nthis is the last line", 60 ) | ||
== "this is\nthe\nfirst\nline\nthis is\nthe\nsecond\nline\nthis is\nthe\nlast\nline" ); | ||
|
||
// Spaces checks | ||
CHECK(wrap("ab cd ", 32) == "ab\ncd"); // Ending spaces | ||
CHECK(wrap("ab cd", 32) == "ab\ncd"); // Middle spaces | ||
CHECK(wrap(" ab cd ", 32) == "ab\ncd"); // Mixed multiple spaces | ||
CHECK(wrap(" ab cd ", 32) == "ab\ncd"); // Mixed multiple spaces | ||
CHECK(wrap(" ab ", 33) == "ab"); // Mixed multiple spaces | ||
CHECK(wrap("ab ", 33) == "ab"); // Ending multiple spaces | ||
CHECK(wrap(" ab", 33) == "ab"); | ||
|
||
// Only spaces | ||
CHECK(wrap(" ", 33) == ""); | ||
CHECK(wrap(" ", 33) == ""); | ||
|
||
CHECK(wrap("ab cd ", 100) == "ab cd"); | ||
CHECK(wrap("ab cd", 100) == "ab cd"); // Known corner case - we trim multiple spaces | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// License: Apache 2.0. See LICENSE file in root directory. | ||
// Copyright(c) 2020 Intel Corporation. All Rights Reserved. | ||
|
||
//#cmake:add-file ../../../common/utilities/string/split.h | ||
|
||
#include "common.h" | ||
#include "../../../common/utilities/string/split.h" | ||
|
||
using namespace utilities::string; | ||
|
||
TEST_CASE("split_string_by_newline", "[string]") | ||
{ | ||
// split size check | ||
CHECK(split("" , '\n').size() == 0); | ||
CHECK(split("abc", '\n').size() == 1); | ||
CHECK(split("abc\nabc", '\n').size() == 2); | ||
CHECK(split("a\nbc\nabc", '\n').size() == 3); | ||
CHECK(split("a\nbc\nabc\n", '\n').size() == 3); | ||
CHECK(split("1-12-123-1234", '-').size() == 4); | ||
|
||
CHECK(split("a\nbc\nabc", '\n')[0] == "a"); | ||
CHECK(split("a\nbc\nabc", '\n')[1] == "bc"); | ||
CHECK(split("a\nbc\nabc", '\n')[2] == "abc"); | ||
CHECK(split("a\nbc\nabc\n", '\n')[2] == "abc"); | ||
|
||
|
||
CHECK(split("1-12-123-1234", '-')[0] == "1"); | ||
CHECK(split("1-12-123-1234", '-')[1] == "12"); | ||
CHECK(split("1-12-123-1234", '-')[2] == "123"); | ||
CHECK(split("1-12-123-1234", '-')[3] == "1234"); | ||
} |