3e8fa71245baf457fdb0d0213485dd07dff123b5
[clinton/Smoothieware.git] / src / modules / utils / panel / PanelScreen.cpp
1 /*
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6 */
7
8 #include "libs/Kernel.h"
9 #include "Panel.h"
10 #include "PanelScreen.h"
11 #include "libs/nuts_bolts.h"
12 #include "libs/utils.h"
13 #include "libs/SerialMessage.h"
14 #include "Gcode.h"
15 #include "LcdBase.h"
16 #include "libs/StreamOutput.h"
17 #include "Robot.h"
18
19 using namespace std;
20
21 // static as it is shared by all screens
22 std::deque<std::string> PanelScreen::command_queue;
23
24 PanelScreen::PanelScreen() {}
25 PanelScreen::~PanelScreen() {}
26
27 void PanelScreen::on_refresh() {}
28
29 void PanelScreen::on_enter() {}
30
31 void PanelScreen::refresh_menu(bool clear)
32 {
33 if (clear) THEPANEL->lcd->clear();
34 for (uint16_t i = THEPANEL->menu_start_line; i < THEPANEL->menu_start_line + min( THEPANEL->menu_rows, THEPANEL->panel_lines ); i++ ) {
35 THEPANEL->lcd->setCursor(2, i - THEPANEL->menu_start_line );
36 this->display_menu_line(i);
37 }
38 THEPANEL->lcd->setCursor(0, THEPANEL->menu_current_line - THEPANEL->menu_start_line );
39 THEPANEL->lcd->printf(">");
40 }
41
42 void PanelScreen::refresh_screen(bool clear)
43 {
44 if (clear) THEPANEL->lcd->clear();
45 for (uint16_t i = THEPANEL->menu_start_line; i < THEPANEL->menu_start_line + min( THEPANEL->menu_rows, THEPANEL->panel_lines ); i++ ) {
46 THEPANEL->lcd->setCursor(0, i - THEPANEL->menu_start_line );
47 this->display_menu_line(i);
48 }
49 }
50
51 PanelScreen *PanelScreen::set_parent(PanelScreen *passed_parent)
52 {
53 this->parent = passed_parent;
54 return this;
55 }
56
57 // Helper for screens to send a gcode, must be called from main loop
58 void PanelScreen::send_gcode(std::string g)
59 {
60 Gcode gcode(g, &(StreamOutput::NullStream));
61 THEKERNEL->call_event(ON_GCODE_RECEIVED, &gcode );
62 }
63
64 void PanelScreen::send_gcode(const char *gm_code, char parameter, float value)
65 {
66 char buf[132];
67 int n = snprintf(buf, sizeof(buf), "%s %c%f", gm_code, parameter, value);
68 string g(buf, n);
69 send_gcode(g);
70 }
71
72 // Helper to send commands, may be called from on_idle will delegate all commands to on_main_loop
73 // may contain multiple commands separated by \n
74 void PanelScreen::send_command(const char *gcstr)
75 {
76 string cmd(gcstr);
77 while (cmd.size() > 0) {
78 size_t b = cmd.find_first_of("\n");
79 if ( b == string::npos ) {
80 command_queue.push_back(cmd);
81 break;
82 }
83 command_queue.push_back(cmd.substr( 0, b ));
84 cmd = cmd.substr(b + 1);
85 }
86 }
87
88 void PanelScreen::get_current_pos(float *cp)
89 {
90 Robot::wcs_t mpos= THEKERNEL->robot->get_axis_position();
91 Robot::wcs_t pos= THEKERNEL->robot->mcs2wcs(mpos);
92 cp[0]= THEKERNEL->robot->from_millimeters(std::get<X_AXIS>(pos));
93 cp[1]= THEKERNEL->robot->from_millimeters(std::get<Y_AXIS>(pos));
94 cp[2]= THEKERNEL->robot->from_millimeters(std::get<Z_AXIS>(pos));
95 }
96
97 void PanelScreen::on_main_loop()
98 {
99 // for each command in queue send it
100 while(command_queue.size() > 0) {
101 struct SerialMessage message;
102 message.message = command_queue.front();
103 command_queue.pop_front();
104 message.stream = &(StreamOutput::NullStream);
105 THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
106 }
107 }