913{
914
915 auto update_lines = [this](uint64_t start_id, uint64_t end_id) {
916 std::vector<Line> ret;
917 ret.reserve(end_id - start_id + 1);
918
919
920
921 const size_t file_size =
m_file.size();
922 for (uint64_t id = start_id; id <= end_id; ++id) {
923
924
925 const size_t start =
id == 1 ? 0 : std::min(
m_lines_ends[
id - 2], file_size);
927 const size_t original_len =
end > start ?
end - start : 0;
928
929 const size_t len = std::min(original_len, (size_t) 55 * 4);
930 std::string gline(
m_file.data() + start, len);
931
932
933
934 if (len < original_len ||
utf8_offset(gline, 55) < gline.size())
935 gline = gline.substr(0,
utf8_offset(gline, 52)) +
"...";
936
937 std::string command, parameters, comment;
938 const size_t comment_start = gline.find(';');
939 if (comment_start == std::string::npos)
940 command = gline;
941 else {
942 command = gline.substr(0, comment_start);
943 comment = gline.substr(comment_start);
944 }
945
946
947 if (!command.empty()) {
948 std::vector<std::string> tokens;
949 boost::split(tokens, command, boost::is_any_of(" "), boost::token_compress_on);
950 command = tokens.front();
951 if (tokens.size() > 1) {
952 for (size_t i = 1; i < tokens.size(); ++i) {
953 parameters += " " + tokens[i];
954 }
955 }
956 }
957 ret.push_back({command, parameters, comment});
958 }
959 return ret;
960 };
961
964 static const ImVec4 COMMAND_COLOR = {0.8f, 0.8f, 0.0f, 1.0f};
965 static const ImVec4 PARAMETERS_COLOR = { 1.0f, 1.0f, 1.0f, 1.0f };
966 static const ImVec4 COMMENT_COLOR = { 0.7f, 0.7f, 0.7f, 1.0f };
967
969 return;
970
971
972 const float wnd_height = bottom - top;
973
974
975 const float text_height = ImGui::CalcTextSize("0").y;
976 const ImGuiStyle&
style = ImGui::GetStyle();
977 const uint64_t lines_count =
static_cast<uint64_t
>((wnd_height - 2.0f *
style.WindowPadding.y +
style.ItemSpacing.y) / (text_height +
style.ItemSpacing.y));
978
979 if (lines_count == 0)
980 return;
981
982
983 const uint64_t half_lines_count = lines_count / 2;
984 uint64_t start_id = (curr_line_id >= half_lines_count) ? curr_line_id - half_lines_count : 0;
985 uint64_t end_id = start_id + lines_count - 1;
986 if (end_id >=
static_cast<uint64_t
>(
m_lines_ends.size())) {
987 end_id =
static_cast<uint64_t
>(
m_lines_ends.size()) - 1;
988 start_id = end_id - lines_count + 1;
989 }
990
991
993 try
994 {
995 *
const_cast<std::vector<Line>*
>(&
m_lines) = update_lines(start_id, end_id);
996 }
997 catch (...)
998 {
999 BOOST_LOG_TRIVIAL(error) <<
"Error while loading from file " <<
m_filename <<
". Cannot show G-code window.";
1000 return;
1001 }
1004 }
1005
1006
1007 const float id_width = ImGui::CalcTextSize(std::to_string(end_id).c_str()).x;
1008
1009 float required_width = 0.0f;
1010 {
1011 float max_text_width = id_width;
1013 float w = 0.0f;
1014
1015 if (!line.command.empty())
1016 w += ImGui::CalcTextSize(line.command.c_str()).x;
1017
1018 if (!line.parameters.empty())
1019 w += ImGui::CalcTextSize(line.parameters.c_str()).x;
1020
1021 if (!line.comment.empty())
1022 w += ImGui::CalcTextSize(line.comment.c_str()).x;
1023
1024
1025 w += 3 * ImGui::GetStyle().ItemSpacing.x;
1026
1027 if (w > max_text_width)
1028 max_text_width = w;
1029 }
1030
1031 required_width = id_width + max_text_width;
1032 }
1033
1034 ImGuiWrapper& imgui = *wxGetApp().imgui();
1035
1036
1037 imgui.set_next_window_pos(right, top + 6 *
m_scale, ImGuiCond_Always, 1.0f, 0.0f);
1038 ImGui::SetNextWindowSize(ImVec2(required_width, wnd_height), ImGuiCond_Always);
1039 ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f *
m_scale);
1040 ImGui::SetNextWindowBgAlpha(0.8f);
1041 imgui.begin(std::string("G-code"), ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove);
1042
1043
1044 const float f_lines_count = static_cast<float>(lines_count);
1045 ImGui::SetCursorPosY(0.5f * (wnd_height - f_lines_count * text_height - (f_lines_count - 1.0f) *
style.ItemSpacing.y));
1046
1047
1048 for (uint64_t id = start_id; id <= end_id; ++id) {
1050
1051
1052 if (id == curr_line_id) {
1053
1054 const float pos_y = ImGui::GetCursorScreenPos().y;
1055 const float pos_x = ImGui::GetCursorScreenPos().x;
1056 const float half_ItemSpacing_y = 0.5f *
style.ItemSpacing.y;
1057 const float half_ItemSpacing_x = 0.5f *
style.ItemSpacing.x;
1058
1059
1060
1061 ImGui::GetWindowDrawList()->AddRect({ pos_x - half_ItemSpacing_x, pos_y - half_ItemSpacing_y },
1062 {
right - half_ItemSpacing_x, pos_y + text_height + half_ItemSpacing_y },
1063 ImGui::GetColorU32(SELECTION_RECT_COLOR));
1064 }
1065
1066
1067 const std::string id_str = std::to_string(id);
1068
1069 ImGui::Dummy({ id_width - ImGui::CalcTextSize(id_str.c_str()).x, text_height });
1070 ImGui::SameLine(0.0f, 0.0f);
1071 ImGui::PushStyleColor(ImGuiCol_Text, LINE_NUMBER_COLOR);
1072 imgui.text(id_str);
1073 ImGui::PopStyleColor();
1074
1075 if (!line.command.empty() || !line.comment.empty())
1076 ImGui::SameLine();
1077
1078
1079 if (!line.command.empty()) {
1080 ImGui::PushStyleColor(ImGuiCol_Text, COMMAND_COLOR);
1081 imgui.text(line.command);
1082 ImGui::PopStyleColor();
1083 }
1084
1085
1086 if (!line.parameters.empty()) {
1087 ImGui::SameLine(0.0f, 0.0f);
1088 ImGui::PushStyleColor(ImGuiCol_Text, PARAMETERS_COLOR);
1089 imgui.text(line.parameters);
1090 ImGui::PopStyleColor();
1091 }
1092
1093
1094 if (!line.comment.empty()) {
1095 if (!line.command.empty())
1096 ImGui::SameLine(0.0f, 0.0f);
1097 ImGui::PushStyleColor(ImGuiCol_Text, COMMENT_COLOR);
1098 imgui.text(line.comment);
1099 ImGui::PopStyleColor();
1100 }
1101 }
1102
1103 imgui.end();
1104 ImGui::PopStyleVar();
1105}
#define style
Definition WipeTowerDialog.cpp:101
float m_scale
Definition GCodeViewer.hpp:151
std::vector< Line > m_lines
Definition GCodeViewer.hpp:148
Definition GCodeViewer.hpp:135
static const ImVec4 COL_ORANGE_LIGHT
Definition ImGuiWrapper.hpp:387
static const ImVec4 COL_ORANGE_DARK
Definition ImGuiWrapper.hpp:386
T * end(Slic3r::Mat< N, M, T > &mat)
Definition Point.hpp:841
static size_t utf8_offset(const std::string &str, size_t count)
Definition GCodeViewer.cpp:899
@ right
Definition MarchingSquares.hpp:190