|
@@ -7,6 +7,27 @@
|
7
|
7
|
#include "stepper.h"
|
8
|
8
|
#include "configuration_store.h"
|
9
|
9
|
|
|
10
|
+/**
|
|
11
|
+ * REVERSE_MENU_DIRECTION
|
|
12
|
+ *
|
|
13
|
+ * To reverse the menu direction we need a general way to reverse
|
|
14
|
+ * the direction of the encoder everywhere. So encoderDirection is
|
|
15
|
+ * added to allow the encoder to go the other way.
|
|
16
|
+ *
|
|
17
|
+ * This behavior is limited to scrolling Menus and SD card listings,
|
|
18
|
+ * and is disabled in other contexts.
|
|
19
|
+ */
|
|
20
|
+#if ENABLED(REVERSE_MENU_DIRECTION)
|
|
21
|
+ int8_t encoderDirection = 1;
|
|
22
|
+ #define ENCODER_DIRECTION_NORMAL() (encoderDirection = 1)
|
|
23
|
+ #define ENCODER_DIRECTION_MENUS() (encoderDirection = -1)
|
|
24
|
+#else
|
|
25
|
+ #define ENCODER_DIRECTION_NORMAL() ;
|
|
26
|
+ #define ENCODER_DIRECTION_MENUS() ;
|
|
27
|
+#endif
|
|
28
|
+
|
|
29
|
+uint8_t blink = 0; // Variable for animation
|
|
30
|
+
|
10
|
31
|
int8_t encoderDiff; // updated from interrupt context and added to encoderPosition every LCD update
|
11
|
32
|
|
12
|
33
|
bool encoderRateMultiplierEnabled;
|
|
@@ -130,6 +151,7 @@ static void lcd_status_screen();
|
130
|
151
|
* START_MENU generates the init code for a menu function
|
131
|
152
|
*/
|
132
|
153
|
#define START_MENU() do { \
|
|
154
|
+ ENCODER_DIRECTION_MENUS(); \
|
133
|
155
|
encoderRateMultiplierEnabled = false; \
|
134
|
156
|
if (encoderPosition > 0x8000) encoderPosition = 0; \
|
135
|
157
|
uint8_t encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; \
|
|
@@ -209,7 +231,7 @@ static void lcd_status_screen();
|
209
|
231
|
#define MENU_MULTIPLIER_ITEM_EDIT_CALLBACK(type, label, args...) MENU_ITEM(setting_edit_callback_ ## type, label, PSTR(label), ## args)
|
210
|
232
|
#endif //!ENCODER_RATE_MULTIPLIER
|
211
|
233
|
#define END_MENU() \
|
212
|
|
- if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * (ENCODER_STEPS_PER_MENU_ITEM) - 1; encoderLine = encoderPosition / ENCODER_STEPS_PER_MENU_ITEM; }\
|
|
234
|
+ if (encoderLine >= _menuItemNr) { encoderPosition = _menuItemNr * (ENCODER_STEPS_PER_MENU_ITEM) - 1; encoderLine = _menuItemNr - 1; }\
|
213
|
235
|
if (encoderLine >= currentMenuViewOffset + LCD_HEIGHT) { currentMenuViewOffset = encoderLine - (LCD_HEIGHT) + 1; lcdDrawUpdate = 1; _lineNr = currentMenuViewOffset - 1; _drawLineNr = -1; } \
|
214
|
236
|
} } while(0)
|
215
|
237
|
|
|
@@ -280,6 +302,7 @@ static void lcd_goto_previous_menu() { lcd_goto_menu(prevMenu, true, prevEncoder
|
280
|
302
|
*/
|
281
|
303
|
|
282
|
304
|
static void lcd_status_screen() {
|
|
305
|
+ ENCODER_DIRECTION_NORMAL();
|
283
|
306
|
encoderRateMultiplierEnabled = false;
|
284
|
307
|
|
285
|
308
|
#if ENABLED(LCD_PROGRESS_BAR)
|
|
@@ -464,6 +487,7 @@ void lcd_set_home_offsets() {
|
464
|
487
|
#if ENABLED(BABYSTEPPING)
|
465
|
488
|
|
466
|
489
|
static void _lcd_babystep(int axis, const char* msg) {
|
|
490
|
+ ENCODER_DIRECTION_NORMAL();
|
467
|
491
|
if (encoderPosition != 0) {
|
468
|
492
|
babystepsTodo[axis] += (BABYSTEP_MULTIPLICATOR) * (int)encoderPosition;
|
469
|
493
|
encoderPosition = 0;
|
|
@@ -828,6 +852,7 @@ float move_menu_scale;
|
828
|
852
|
static void lcd_move_menu_axis();
|
829
|
853
|
|
830
|
854
|
static void _lcd_move(const char* name, AxisEnum axis, int min, int max) {
|
|
855
|
+ ENCODER_DIRECTION_NORMAL();
|
831
|
856
|
if ((encoderPosition != 0) && (movesplanned() <= 3)) {
|
832
|
857
|
refresh_cmd_timeout();
|
833
|
858
|
current_position[axis] += float((int)encoderPosition) * move_menu_scale;
|
|
@@ -855,6 +880,7 @@ static void lcd_move_e(
|
855
|
880
|
uint8_t e
|
856
|
881
|
#endif
|
857
|
882
|
) {
|
|
883
|
+ ENCODER_DIRECTION_NORMAL();
|
858
|
884
|
#if EXTRUDERS > 1
|
859
|
885
|
unsigned short original_active_extruder = active_extruder;
|
860
|
886
|
active_extruder = e;
|
|
@@ -1263,6 +1289,7 @@ static void lcd_control_volumetric_menu() {
|
1263
|
1289
|
*/
|
1264
|
1290
|
#if ENABLED(HAS_LCD_CONTRAST)
|
1265
|
1291
|
static void lcd_set_contrast() {
|
|
1292
|
+ ENCODER_DIRECTION_NORMAL();
|
1266
|
1293
|
if (encoderPosition != 0) {
|
1267
|
1294
|
#if ENABLED(U8GLIB_LM6059_AF)
|
1268
|
1295
|
lcd_contrast += encoderPosition;
|
|
@@ -1331,6 +1358,7 @@ static void lcd_control_volumetric_menu() {
|
1331
|
1358
|
*
|
1332
|
1359
|
*/
|
1333
|
1360
|
void lcd_sdcard_menu() {
|
|
1361
|
+ ENCODER_DIRECTION_MENUS();
|
1334
|
1362
|
if (lcdDrawUpdate == 0 && LCD_CLICKED == 0) return; // nothing to do (so don't thrash the SD card)
|
1335
|
1363
|
uint16_t fileCnt = card.getnrfilenames();
|
1336
|
1364
|
START_MENU();
|
|
@@ -1371,9 +1399,31 @@ static void lcd_control_volumetric_menu() {
|
1371
|
1399
|
*
|
1372
|
1400
|
* Functions for editing single values
|
1373
|
1401
|
*
|
|
1402
|
+ * The "menu_edit_type" macro generates the functions needed to edit a numerical value.
|
|
1403
|
+ *
|
|
1404
|
+ * For example, menu_edit_type(int, int3, itostr3, 1) expands into these functions:
|
|
1405
|
+ *
|
|
1406
|
+ * bool _menu_edit_int3();
|
|
1407
|
+ * void menu_edit_int3(); // edit int (interactively)
|
|
1408
|
+ * void menu_edit_callback_int3(); // edit int (interactively) with callback on completion
|
|
1409
|
+ * static void _menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue);
|
|
1410
|
+ * static void menu_action_setting_edit_int3(const char* pstr, int* ptr, int minValue, int maxValue);
|
|
1411
|
+ * static void menu_action_setting_edit_callback_int3(const char* pstr, int* ptr, int minValue, int maxValue, menuFunc_t callback); // edit int with callback
|
|
1412
|
+ *
|
|
1413
|
+ * You can then use one of the menu macros to present the edit interface:
|
|
1414
|
+ * MENU_ITEM_EDIT(int3, MSG_SPEED, &feedrate_multiplier, 10, 999)
|
|
1415
|
+ *
|
|
1416
|
+ * This expands into a more primitive menu item:
|
|
1417
|
+ * MENU_ITEM(setting_edit_int3, MSG_SPEED, PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
|
|
1418
|
+ *
|
|
1419
|
+ *
|
|
1420
|
+ * Also: MENU_MULTIPLIER_ITEM_EDIT, MENU_ITEM_EDIT_CALLBACK, and MENU_MULTIPLIER_ITEM_EDIT_CALLBACK
|
|
1421
|
+ *
|
|
1422
|
+ * menu_action_setting_edit_int3(PSTR(MSG_SPEED), &feedrate_multiplier, 10, 999)
|
1374
|
1423
|
*/
|
1375
|
1424
|
#define menu_edit_type(_type, _name, _strFunc, scale) \
|
1376
|
1425
|
bool _menu_edit_ ## _name () { \
|
|
1426
|
+ ENCODER_DIRECTION_NORMAL(); \
|
1377
|
1427
|
bool isClicked = LCD_CLICKED; \
|
1378
|
1428
|
if ((int32_t)encoderPosition < 0) encoderPosition = 0; \
|
1379
|
1429
|
if ((int32_t)encoderPosition > maxEditValue) encoderPosition = maxEditValue; \
|
|
@@ -1937,28 +1987,25 @@ void lcd_reset_alert_level() { lcd_status_message_level = 0; }
|
1937
|
1987
|
buttons = ~newbutton; //invert it, because a pressed switch produces a logical 0
|
1938
|
1988
|
#endif //!NEWPANEL
|
1939
|
1989
|
|
|
1990
|
+ #if ENABLED(REVERSE_MENU_DIRECTION)
|
|
1991
|
+ #define ENCODER_DIFF_CW (encoderDiff += encoderDirection)
|
|
1992
|
+ #define ENCODER_DIFF_CCW (encoderDiff -= encoderDirection)
|
|
1993
|
+ #else
|
|
1994
|
+ #define ENCODER_DIFF_CW (encoderDiff++)
|
|
1995
|
+ #define ENCODER_DIFF_CCW (encoderDiff--)
|
|
1996
|
+ #endif
|
|
1997
|
+ #define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: ENCODER_DIFF_CW; break; case _E2: ENCODER_DIFF_CCW; }
|
|
1998
|
+
|
1940
|
1999
|
//manage encoder rotation
|
1941
|
2000
|
uint8_t enc = 0;
|
1942
|
2001
|
if (buttons & EN_A) enc |= B01;
|
1943
|
2002
|
if (buttons & EN_B) enc |= B10;
|
1944
|
2003
|
if (enc != lastEncoderBits) {
|
1945
|
2004
|
switch (enc) {
|
1946
|
|
- case encrot0:
|
1947
|
|
- if (lastEncoderBits == encrot3) encoderDiff++;
|
1948
|
|
- else if (lastEncoderBits == encrot1) encoderDiff--;
|
1949
|
|
- break;
|
1950
|
|
- case encrot1:
|
1951
|
|
- if (lastEncoderBits == encrot0) encoderDiff++;
|
1952
|
|
- else if (lastEncoderBits == encrot2) encoderDiff--;
|
1953
|
|
- break;
|
1954
|
|
- case encrot2:
|
1955
|
|
- if (lastEncoderBits == encrot1) encoderDiff++;
|
1956
|
|
- else if (lastEncoderBits == encrot3) encoderDiff--;
|
1957
|
|
- break;
|
1958
|
|
- case encrot3:
|
1959
|
|
- if (lastEncoderBits == encrot2) encoderDiff++;
|
1960
|
|
- else if (lastEncoderBits == encrot0) encoderDiff--;
|
1961
|
|
- break;
|
|
2005
|
+ case encrot0: ENCODER_SPIN(encrot3, encrot1); break;
|
|
2006
|
+ case encrot1: ENCODER_SPIN(encrot0, encrot2); break;
|
|
2007
|
+ case encrot2: ENCODER_SPIN(encrot1, encrot3); break;
|
|
2008
|
+ case encrot3: ENCODER_SPIN(encrot2, encrot0); break;
|
1962
|
2009
|
}
|
1963
|
2010
|
}
|
1964
|
2011
|
lastEncoderBits = enc;
|
|
@@ -2242,6 +2289,7 @@ char* ftostr52(const float& x) {
|
2242
|
2289
|
* - Click saves the Z and goes to the next mesh point
|
2243
|
2290
|
*/
|
2244
|
2291
|
static void _lcd_level_bed() {
|
|
2292
|
+ ENCODER_DIRECTION_NORMAL();
|
2245
|
2293
|
if ((encoderPosition != 0) && (movesplanned() <= 3)) {
|
2246
|
2294
|
refresh_cmd_timeout();
|
2247
|
2295
|
current_position[Z_AXIS] += float((int)encoderPosition) * (MBL_Z_STEP);
|