aboutsummaryrefslogtreecommitdiff
path: root/Marlin/src/lcd/extui/lib/anycubic_chiron/FileNavigator.cpp
blob: 19f8ec81bc5b4a87d40066e7fd93a028b6512d12 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/**
 * Marlin 3D Printer Firmware
 * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
 *
 * Based on Sprinter and grbl.
 * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
 *
 * This program 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.
 *
 * This program 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

/**
 * lcd/extui/lib/FileNavigator.cpp
 *
 * Extensible_UI implementation for Anycubic Chiron
 * Written By Nick Wells, 2020 [https://github.com/SwiftNick]
 *  (not affiliated with Anycubic, Ltd.)
 */

/***************************************************************************
 * The AC panel wants files in block of 4 and can only display a flat list *
 * This library allows full folder traversal.                              *
 ***************************************************************************/

#include "../../../../inc/MarlinConfigPre.h"

#if ENABLED(ANYCUBIC_LCD_CHIRON)

#include "FileNavigator.h"
#include "chiron_tft.h"

using namespace ExtUI;

namespace Anycubic {

  FileNavigator filenavigator;

  FileList  FileNavigator::filelist;                          // Instance of the Marlin file API
  char      FileNavigator::currentfoldername[MAX_PATH_LEN];   // Current folder path
  uint16_t  FileNavigator::lastindex;
  uint8_t   FileNavigator::folderdepth;
  uint16_t  FileNavigator::currentindex;                      // override the panel request

  FileNavigator::FileNavigator() { reset(); }

  void FileNavigator::reset() {
    currentfoldername[0] = '\0';
    folderdepth  = 0;
    currentindex = 0;
    lastindex    = 0;
    // Start at root folder
    while (!filelist.isAtRootDir()) filelist.upDir();
    refresh();
  }

  void FileNavigator::refresh() { filelist.refresh(); }

  void FileNavigator::getFiles(uint16_t index) {
    uint8_t files = 4;
    if (index == 0) currentindex = 0;

    // Each time we change folder we reset the file index to 0 and keep track
    // of the current position as the TFT panel isnt aware of folders trees.
    if (index > 0) {
      --currentindex; // go back a file to take account off the .. we added to the root.
      if (index > lastindex)
        currentindex += files;
      else
        currentindex = currentindex < 4 ? 0 : currentindex - files;
    }
    lastindex = index;

    #if ACDEBUG(AC_FILE)
      SERIAL_ECHOLNPAIR("index=", index, " currentindex=", currentindex);
    #endif

    if (currentindex == 0 && folderdepth > 0) { // Add a link to go up a folder
      TFTSer.println("<<");
      TFTSer.println("..");
      files--;
    }

    for (uint16_t seek = currentindex; seek < currentindex + files; seek++) {
      if (filelist.seek(seek)) {
        sendFile();
        #if ACDEBUG(AC_FILE)
          SERIAL_ECHOLNPAIR("-", seek, " '", filelist.longFilename(), "' '", currentfoldername, "", filelist.shortFilename(), "'\n");
        #endif
      }
    }
  }

  void FileNavigator::sendFile() {
    // send the file and folder info to the panel
    // this info will be returned when the file is selected
    // Permitted special characters in file name -_*#~
    // Panel can display 22 characters per line
    if (filelist.isDir()) {
      //TFTSer.print(currentfoldername);
      TFTSer.println(filelist.shortFilename());
      TFTSer.print(filelist.shortFilename());
      TFTSer.println("/");
    }
    else {
      // Logical Name
      TFTSer.print("/");
      if (folderdepth > 0) TFTSer.print(currentfoldername);

      TFTSer.println(filelist.shortFilename());

      // Display Name
      TFTSer.println(filelist.longFilename());
    }
  }
  void FileNavigator::changeDIR(char *folder) {
    #if ACDEBUG(AC_FILE)
      SERIAL_ECHOLNPAIR("currentfolder: ", currentfoldername, "  New: ", folder);
    #endif
    if (folderdepth >= MAX_FOLDER_DEPTH) return; // limit the folder depth
    strcat(currentfoldername, folder);
    strcat(currentfoldername, "/");
    filelist.changeDir(folder);
    refresh();
    folderdepth++;
    currentindex = 0;
  }

  void FileNavigator::upDIR() {
    filelist.upDir();
    refresh();
    folderdepth--;
    currentindex = 0;
    // Remove the last child folder from the stored path
    if (folderdepth == 0) {
      currentfoldername[0] = '\0';
      reset();
    }
    else {
      char *pos = nullptr;
      for (uint8_t f = 0; f < folderdepth; f++)
        pos = strchr(currentfoldername, '/');

      *(pos + 1) = '\0';
    }
    #if ACDEBUG(AC_FILE)
      SERIAL_ECHOLNPAIR("depth: ", folderdepth, " currentfoldername: ", currentfoldername);
    #endif
  }

  char* FileNavigator::getCurrentFolderName() { return currentfoldername; }
}

#endif // ANYCUBIC_LCD_CHIRON