Add laser menu
[clinton/Smoothieware.git] / src / modules / utils / panel / screens / ModifyValuesScreen.cpp
CommitLineData
2fa50ca0
JM
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#include "ModifyValuesScreen.h"
8#include "libs/Kernel.h"
9#include "Config.h"
10#include "checksumm.h"
11#include "LcdBase.h"
12#include "Panel.h"
13#include "ConfigValue.h"
14
15#include <string.h>
16
17#include <algorithm>
18
19using namespace std;
20
21#define MENU_CONTROL_MODE 0
22#define VALUE_CONTROL_MODE 1
23
383c9c1c 24ModifyValuesScreen::ModifyValuesScreen(bool delete_on_exit)
2fa50ca0 25{
383c9c1c
JM
26 this->delete_on_exit= delete_on_exit;
27 this->execute_function = -1;
28 this->control_mode = MENU_CONTROL_MODE;
2fa50ca0
JM
29}
30
cee1bb2d
JM
31ModifyValuesScreen::~ModifyValuesScreen()
32{
33 // free up the strdup() name
34 for(auto i : menu_items) {
35 free(std::get<0>(i));
36 }
37}
38
383c9c1c
JM
39void ModifyValuesScreen::on_exit()
40{
41 if(this->delete_on_exit)
42 delete this;
43}
44
2fa50ca0
JM
45void ModifyValuesScreen::on_enter()
46{
cee1bb2d
JM
47 THEPANEL->enter_menu_mode();
48 THEPANEL->setup_menu(menu_items.size() + 1);
2fa50ca0
JM
49 this->refresh_menu();
50}
51
52void ModifyValuesScreen::on_refresh()
53{
cee1bb2d 54 if ( THEPANEL->menu_change() ) {
2fa50ca0
JM
55 this->refresh_menu();
56 }
57
58 if (this->control_mode == VALUE_CONTROL_MODE) {
59
cee1bb2d 60 if ( THEPANEL->click() ) {
2fa50ca0 61 // done changing value
7ddf5c6b 62 this->new_value = THEPANEL->get_control_value();
289380f2 63 if(!this->instant) execute_function= selected_item; // this causes on_main_loop to change the value
2fa50ca0 64 this->control_mode = MENU_CONTROL_MODE;
cee1bb2d 65 THEPANEL->enter_menu_mode(true);
2fa50ca0 66
cee1bb2d 67 } else if (THEPANEL->control_value_change()) {
7ddf5c6b
JM
68 float value = THEPANEL->get_control_value();
69 if(!isnan(this->min_value) && value < this->min_value) {
70 THEPANEL->set_control_value((value = this->min_value));
cee1bb2d 71 THEPANEL->reset_counter();
2fa50ca0 72 }
7ddf5c6b
JM
73 if(!isnan(this->max_value) && value > this->max_value) {
74 THEPANEL->set_control_value((value = this->max_value));
cee1bb2d 75 THEPANEL->reset_counter();
2fa50ca0 76 }
cee1bb2d 77 THEPANEL->lcd->setCursor(0, 2);
7ddf5c6b 78 THEPANEL->lcd->printf("%10.3f ", value);
8b6bc932
JM
79 if(this->instant) {
80 // NOTE this cannot be something that needs to be set in on_main_loop
81 std::get<2>(menu_items[selected_item])(value);
82 }
2fa50ca0
JM
83 }
84
85 } else {
cee1bb2d
JM
86 if ( THEPANEL->click() ) {
87 this->clicked_menu_entry(THEPANEL->get_menu_current_line());
2fa50ca0
JM
88 }
89 }
90}
91
92void ModifyValuesScreen::display_menu_line(uint16_t line)
93{
94 if (line == 0) {
cee1bb2d 95 THEPANEL->lcd->printf("Back");
2fa50ca0
JM
96 } else {
97 line--;
98 const char *name = std::get<0>(menu_items[line]);
99 float value = std::get<1>(menu_items[line])();
f7684487 100 THEPANEL->lcd->printf("%-10s %7.2f", name, value);
2fa50ca0
JM
101 }
102}
103
104void ModifyValuesScreen::clicked_menu_entry(uint16_t line)
105{
106 if (line == 0) {
cee1bb2d 107 THEPANEL->enter_screen(this->parent);
2fa50ca0
JM
108
109 } else {
110 line--;
111 this->selected_item = line;
112 this->control_mode = VALUE_CONTROL_MODE;
113
114 const char *name = std::get<0>(menu_items[line]);
115 float value = std::get<1>(menu_items[line])();
116 float inc= std::get<3>(menu_items[line]);
cee1bb2d 117 THEPANEL->enter_control_mode(inc, inc / 10);
2fa50ca0
JM
118 this->min_value= std::get<4>(menu_items[line]);
119 this->max_value= std::get<5>(menu_items[line]);
8b6bc932 120 this->instant= std::get<6>(menu_items[line]);
2fa50ca0 121
cee1bb2d
JM
122 THEPANEL->set_control_value(value);
123 THEPANEL->lcd->clear();
124 THEPANEL->lcd->setCursor(0, 0);
125 THEPANEL->lcd->printf("%s", name);
126 THEPANEL->lcd->setCursor(0, 2);
127 THEPANEL->lcd->printf("%10.3f", value);
2fa50ca0
JM
128 }
129}
130
131// queuing commands needs to be done from main loop
132void ModifyValuesScreen::on_main_loop()
133{
134 // issue command
135 if (execute_function == -1) return;
136
137 // execute the setter function for the specified menu item
7ddf5c6b 138 std::get<2>(menu_items[execute_function])(this->new_value);
2fa50ca0
JM
139 execute_function = -1;
140}
141
3e49ef2d
JM
142void ModifyValuesScreen::addMenuItem(const MenuItemType& item)
143{
144 menu_items.push_back(item);
145}
146
8b6bc932 147void ModifyValuesScreen::addMenuItem(const char *name, std::function<float()> getter, std::function<void(float)> setter, float inc, float min, float max, bool instant)
2fa50ca0 148{
f7684487
JM
149 string n(name);
150 if(n.size() > 10) {
151 n= n.substr(0, 10);
152 }
8b6bc932 153 addMenuItem(make_tuple(strdup(n.c_str()), getter, setter, inc, min, max, instant));
2fa50ca0 154}