├── .github └── workflows │ ├── build.yml │ └── build_win.yml ├── .gitignore ├── AppDir └── usr │ └── share │ ├── applications │ └── Candle2.desktop │ └── icons │ └── hicolor │ └── 256x256 │ └── apps │ └── default.png ├── LICENSE ├── Readme.md ├── Screenshots └── image1.png └── src ├── GrIP ├── CRC.c ├── CRC.h ├── GrIP.cpp └── GrIP.h ├── candle2.pro ├── drawers ├── gcodedrawer.cpp ├── gcodedrawer.h ├── heightmapborderdrawer.cpp ├── heightmapborderdrawer.h ├── heightmapgriddrawer.cpp ├── heightmapgriddrawer.h ├── heightmapinterpolationdrawer.cpp ├── heightmapinterpolationdrawer.h ├── origindrawer.cpp ├── origindrawer.h ├── selectiondrawer.cpp ├── selectiondrawer.h ├── shaderdrawable.cpp ├── shaderdrawable.h ├── tooldrawer.cpp └── tooldrawer.h ├── fonts.qrc ├── frmabout.cpp ├── frmabout.h ├── frmabout.ui ├── frmmain.cpp ├── frmmain.h ├── frmmain.ui ├── frmmain_event.cpp ├── frmmain_heightmap.cpp ├── frmmain_jogcontrol.cpp ├── frmmain_processresponse.cpp ├── frmmain_settings.cpp ├── frmmain_util.cpp ├── frmsettings.cpp ├── frmsettings.h ├── frmsettings.ui ├── images.qrc ├── images ├── 1401561986_chevron-left.png ├── 1401562173_chevron-down.png ├── 1401562173_chevron-right.png ├── 1401562173_chevron-up.png ├── 1401562699_icon-arrow-down-b.png ├── 1401562699_icon-arrow-up-b.png ├── axis_return.png ├── axis_return.svg ├── axis_zero.png ├── axis_zero.svg ├── brake.png ├── candle.ico ├── candle_16.png ├── candle_20.png ├── candle_256.png ├── collapse.png ├── collapse_disabled.png ├── cube.png ├── cubeFront.png ├── cubeLeft.png ├── cubeTop.png ├── cutter.png ├── cutter1.ico ├── erase_1.png ├── expand.png ├── expand_disabled.png ├── fit_1.png ├── g7567.png ├── grblControl1.ico ├── grblControl2.ico ├── guard.png ├── guard.svg ├── handle2s.png ├── handle2s1.png ├── handle2sh.png ├── handle_horizontal.png ├── handle_small.png ├── handle_vertical.png ├── home.png ├── home.svg ├── icon.png ├── icon.svg ├── icon1.png ├── icon1.svg ├── icon2.svg ├── icon3.svg ├── icon3_16.png ├── icon3_20.png ├── icon3png.png ├── icons.svg ├── icons_arrow.svg ├── laser.svg ├── laser1.svg ├── list.png ├── list_collapsed.png ├── menu.png ├── menu.svg ├── menu_13.png ├── menu_16.png ├── menu_collapse.png ├── menu_collapse_13.png ├── menu_collapse_16.png ├── num1.png ├── num1.svg ├── num2.png ├── num3.png ├── num4.png ├── origin.png ├── origin.svg ├── pause.png ├── play.png ├── restart.png ├── restart.svg ├── run.png ├── run.svg ├── safe_z.png ├── safe_z.svg ├── search_for_home2.png ├── search_for_z.png ├── search_home.svg ├── search_z.svg ├── send_1.png ├── shadow.png ├── small_arrow.png ├── small_arrow.svg ├── stop.png ├── unlock.png ├── zero_z.png └── zero_z.svg ├── interface ├── SerialInterface.cpp └── SerialInterface.h ├── main.cpp ├── parser ├── arcproperties.cpp ├── arcproperties.h ├── gcodeparser.cpp ├── gcodeparser.h ├── gcodepreprocessorutils.cpp ├── gcodepreprocessorutils.h ├── gcodeviewparse.cpp ├── gcodeviewparse.h ├── linesegment.cpp ├── linesegment.h ├── pointsegment.cpp └── pointsegment.h ├── protocol ├── grbl1_1.cpp └── grbl1_1.h ├── shaders.qrc ├── shaders ├── fshader.glsl └── vshader.glsl ├── tables ├── gcodetablemodel.cpp ├── gcodetablemodel.h ├── heightmaptablemodel.cpp └── heightmaptablemodel.h ├── utils ├── interpolation.h ├── profiles.cpp ├── profiles.h ├── safequeue.h └── util.h └── widgets ├── colorpicker.cpp ├── colorpicker.h ├── combobox.cpp ├── combobox.h ├── comboboxkey.cpp ├── comboboxkey.h ├── glwidget.cpp ├── glwidget.h ├── groupbox.cpp ├── groupbox.h ├── scrollarea.cpp ├── scrollarea.h ├── slider.cpp ├── slider.h ├── sliderbox.cpp ├── sliderbox.h ├── sliderbox.ui ├── styledtoolbutton.cpp ├── styledtoolbutton.h ├── widget.cpp └── widget.h /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Candle2 Linux64 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | build_linux: 11 | 12 | runs-on: ubuntu-20.04 13 | 14 | env: 15 | SOURCE_DIR: ${{ github.workspace }} 16 | QT_VERSION: 5.15.2 17 | ARTIFACT: Candle2_AppImage 18 | 19 | defaults: 20 | run: 21 | shell: bash 22 | 23 | steps: 24 | - name: Install QT 25 | run: | 26 | sudo apt install qt5-default qt5-qmake qtbase5-dev-tools libqt5serialport5-dev -y 27 | 28 | - name: Checkout repo 29 | uses: actions/checkout@v4 30 | 31 | - name: Configure 32 | run: | 33 | mkdir build && cd build 34 | qmake ../src/candle2.pro 35 | cd .. 36 | 37 | - name: Build 38 | run: | 39 | cd build 40 | make -j6 41 | cd .. 42 | 43 | - name: Deploy 44 | run: | 45 | mkdir -p AppDir/usr/bin 46 | mkdir deploy && cd deploy 47 | wget "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" 48 | chmod a+x *.AppImage 49 | cp ../build/Candle2 ../AppDir/usr/bin 50 | ./linuxdeployqt-continuous-x86_64.AppImage ../AppDir/usr/share/applications/Candle2.desktop -verbose=2 51 | ./linuxdeployqt-continuous-x86_64.AppImage ../AppDir/usr/share/applications/Candle2.desktop -verbose=2 -appimage 52 | cd .. 53 | 54 | 55 | - name: Upload 56 | uses: actions/upload-artifact@v4 57 | with: 58 | name: ${{ env.ARTIFACT }} 59 | path: | 60 | deploy/Candle2*.AppImage 61 | 62 | build_win: 63 | runs-on: windows-2022 64 | 65 | env: 66 | SOURCE_DIR: ${{ github.workspace }} 67 | QT_VERSION: 5.15.2 68 | ARTIFACT: candle2-win.zip 69 | 70 | defaults: 71 | run: 72 | shell: cmd 73 | 74 | steps: 75 | - name: Checkout repo 76 | uses: actions/checkout@v4 77 | with: 78 | submodules: recursive 79 | 80 | - name: Get all tags for correct version determination 81 | working-directory: ${{ github.workspace }} 82 | run: | 83 | git fetch --all --tags -f 84 | - name: Install Qt 85 | uses: jurplel/install-qt-action@v3 86 | with: 87 | version: ${{ env.QT_VERSION }} 88 | host: windows 89 | target: desktop 90 | arch: win64_msvc2019_64 91 | dir: ${{ runner.temp }} 92 | setup-python: false 93 | 94 | - name: Download JOM 95 | uses: suisei-cn/actions-download-file@master 96 | with: 97 | url: http://download.qt.io/official_releases/jom/jom.zip 98 | target: ${{ runner.temp }}\ 99 | 100 | - name: Unzip JOM 101 | working-directory: ${{ runner.temp }} 102 | run: | 103 | 7z x jom.zip -ojom 104 | 105 | - name: Create build directory 106 | run: mkdir ${{ runner.temp }}\build 107 | 108 | - name: Set up Visual Studio shell 109 | uses: egor-tensin/vs-shell@v2 110 | with: 111 | arch: x64 112 | 113 | - name: Build 114 | working-directory: ${{ runner.temp }}\build 115 | run: | 116 | qmake -r ${{ env.SOURCE_DIR }}\src\candle2.pro 117 | ${{ runner.temp }}\jom\jom -j3 118 | cd release 119 | windeployqt --qmldir ${{ env.SOURCE_DIR }} Candle2.exe --pdb --release --compiler-runtime 120 | copy C:\Windows\System32\concrt140.dll . 121 | copy C:\Windows\System32\vccorlib140.dll . 122 | copy C:\Windows\System32\msvcp140.dll . 123 | copy C:\Windows\System32\vcruntime140.dll . 124 | 125 | - name: Zip build 126 | working-directory: ${{ runner.temp }} 127 | run: | 128 | 7z a candle2-win.zip ${{ runner.temp }}\build\* -r -x!*.h -x!*.obj -x!*.cpp -x!*.rc -x!*.stash -x!*.Debug -x!*.Release -x!Makefile 129 | 130 | - name: Save build artifact 131 | uses: actions/upload-artifact@v4 132 | with: 133 | name: ${{ env.ARTIFACT }} 134 | path: ${{ runner.temp }}\${{ env.ARTIFACT }} 135 | 136 | release: 137 | needs: [build_linux, build_win] 138 | runs-on: ubuntu-latest 139 | 140 | steps: 141 | - name: Download Artifacts 142 | uses: actions/download-artifact@v4 143 | with: 144 | path: ./ 145 | 146 | - name: List files 147 | run: ls -R ./ 148 | shell: bash 149 | 150 | - name: Update Current Release 151 | uses: andelf/nightly-release@main 152 | env: 153 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 154 | with: 155 | tag_name: latest 156 | name: "Latest Release $$" 157 | draft: false 158 | prerelease: true 159 | body: | 160 | This is the latest binary release. 161 | 162 | files: | 163 | Candle2_AppImage/Candle2*.AppImage 164 | candle2-win.zip/candle2-win.zip 165 | -------------------------------------------------------------------------------- /.github/workflows/build_win.yml: -------------------------------------------------------------------------------- 1 | name: Candle2 Build Win64 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | defaults: 10 | run: 11 | shell: cmd 12 | 13 | env: 14 | SOURCE_DIR: ${{ github.workspace }} 15 | QT_VERSION: 5.15.2 16 | ARTIFACT: candle2-build.zip 17 | 18 | jobs: 19 | build: 20 | runs-on: windows-2022 21 | 22 | steps: 23 | - name: Checkout repo 24 | uses: actions/checkout@v3 25 | with: 26 | submodules: recursive 27 | 28 | - name: Get all tags for correct version determination 29 | working-directory: ${{ github.workspace }} 30 | run: | 31 | git fetch --all --tags -f 32 | - name: Install Qt 33 | uses: jurplel/install-qt-action@v3 34 | with: 35 | version: ${{ env.QT_VERSION }} 36 | host: windows 37 | target: desktop 38 | arch: win64_msvc2019_64 39 | dir: ${{ runner.temp }} 40 | setup-python: false 41 | 42 | - name: Download JOM 43 | uses: suisei-cn/actions-download-file@master 44 | with: 45 | url: http://download.qt.io/official_releases/jom/jom.zip 46 | target: ${{ runner.temp }}\ 47 | 48 | - name: Unzip JOM 49 | working-directory: ${{ runner.temp }} 50 | run: | 51 | 7z x jom.zip -ojom 52 | 53 | - name: Create build directory 54 | run: mkdir ${{ runner.temp }}\build 55 | 56 | - name: Set up Visual Studio shell 57 | uses: egor-tensin/vs-shell@v2 58 | with: 59 | arch: x64 60 | 61 | - name: Build 62 | working-directory: ${{ runner.temp }}\build 63 | run: | 64 | qmake -r ${{ env.SOURCE_DIR }}\src\candle2.pro 65 | ${{ runner.temp }}\jom\jom -j3 66 | cd release 67 | windeployqt --qmldir ${{ env.SOURCE_DIR }} Candle2.exe --pdb --release --compiler-runtime 68 | copy C:\Windows\System32\concrt140.dll . 69 | copy C:\Windows\System32\vccorlib140.dll . 70 | copy C:\Windows\System32\msvcp140.dll . 71 | copy C:\Windows\System32\vcruntime140.dll . 72 | 73 | - name: Zip build 74 | working-directory: ${{ runner.temp }} 75 | run: | 76 | 7z a candle2-build.zip ${{ runner.temp }}\build\* -r -x!*.h -x!*.obj -x!*.cpp -x!*.rc -x!*.stash -x!*.Debug -x!*.Release -x!Makefile 77 | 78 | - name: Save build artifact 79 | uses: actions/upload-artifact@master 80 | with: 81 | name: ${{ env.ARTIFACT }} 82 | path: ${{ runner.temp }}\${{ env.ARTIFACT }} 83 | 84 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | ui_* 3 | moc_* 4 | .qmake.stash 5 | Makefile 6 | Candle2 7 | qrc_* 8 | settings.ini 9 | build-*/ 10 | -------------------------------------------------------------------------------- /AppDir/usr/share/applications/Candle2.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=Candle2 4 | Exec=Candle2 5 | Icon=default 6 | Comment=GRBL control interface in Qt 7 | Terminal=false 8 | Categories=Development; -------------------------------------------------------------------------------- /AppDir/usr/share/icons/hicolor/256x256/apps/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/AppDir/usr/share/icons/hicolor/256x256/apps/default.png -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | Candle 2 2 | ----------- 3 | GRBL and GRBL-Advanced controller application with G-Code visualizer written in Qt. 4 | Forked from [denvi/Candle](https://github.com/Denvi/Candle). 5 | 6 | Supported functions: 7 | * Controlling GRBL-based CNC-Machine via console commands, buttons on form and numpad. 8 | * Monitoring cnc-machine state. 9 | * Loading, editing, saving and sending of G-code files to CNC-Machine. 10 | * Visualizing G-code files. 11 | 12 | System requirements for running "Candle2": 13 | ------------------- 14 | * Windows/Linux x86_x64 15 | * CPU with SSE2 instruction set support 16 | * Graphics card with OpenGL 2.0 support 17 | * 160 MB free storage space 18 | 19 | Build requirements: 20 | ------------------ 21 | Windows: Qt 5.15.2 with MinGW/GCC compiler 22 | 23 | Linux: QT 5.12.2 with GCC 24 | 25 | Downloads: 26 | ---------- 27 | * Releases (Win & Linux): [Candle 2](https://github.com/Schildkroet/Candle2/releases) 28 | 29 | 30 | Candle 2 GUI: 31 | ------------ 32 | ![screenshot](/Screenshots/image1.png) 33 | 34 | -------------------------------------------------------------------------------- /Screenshots/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/Screenshots/image1.png -------------------------------------------------------------------------------- /src/GrIP/CRC.h: -------------------------------------------------------------------------------- 1 | /* 2 | CRC.h - Simple library to calculate 8-, 16-, and 32-Bit CRC 3 | 4 | Copyright (c) 2018 Patrick F. 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | You should have received a copy of the GNU General Public License 16 | along with program. If not, see . 17 | */ 18 | #ifndef CRC_H_INCLUDED 19 | #define CRC_H_INCLUDED 20 | 21 | 22 | #include 23 | 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | 30 | #define RUNTTIME 0 31 | #define TABLE 1 32 | #define HARDWARE 2 33 | 34 | 35 | /* ---------- Defines for 8-bit SAE J1850 CRC calculation (Not reflected) ------------------------------------------------------- */ 36 | #define CRC_8_RESULT_WIDTH 8u 37 | #define CRC_8_POLYNOMIAL 0x1Du 38 | #define CRC_8_INIT_VALUE 0xFFu 39 | #define CRC_8_XOR_VALUE 0xFFu 40 | #define CRC_8_MODE RUNTTIME 41 | 42 | /* ---------- Defines for 16-bit CCITT CRC calculation (Not reflected) ---------------------------------------------------------- */ 43 | #define CRC_16_RESULT_WIDTH 16u 44 | #define CRC_16_POLYNOMIAL 0x1021u 45 | #define CRC_16_INIT_VALUE 0xFFFFu 46 | #define CRC_16_XOR_VALUE 0x0000u 47 | #define CRC_16_MODE RUNTTIME 48 | 49 | /* ---------- Defines for 32-bit CCITT CRC calculation (Reflected) -------------------------------------------------------------- */ 50 | #define CRC_32_RESULT_WIDTH 32u 51 | #define CRC_32_POLYNOMIAL 0x04C11DB7u 52 | #define CRC_32_INIT_VALUE 0xFFFFFFFFu 53 | #define CRC_32_XOR_VALUE 0xFFFFFFFFu 54 | #define CRC_32_MODE RUNTTIME 55 | 56 | 57 | 58 | void CRC_Init(void); 59 | 60 | /** 61 | * This function makes a CRC8 calculation on Length data bytes with SAEJ1850 parameters 62 | * 63 | * RETURN VALUE: 8 bit result of CRC calculation 64 | */ 65 | uint8_t CRC_CalculateCRC8(const uint8_t *Buffer, uint16_t Length); 66 | 67 | /** 68 | * This function makes a CRC16 calculation on Length data bytes 69 | * 70 | * RETURN VALUE: 16 bit result of CRC calculation 71 | */ 72 | uint16_t CRC_CalculateCRC16(const uint8_t *Buffer, uint8_t Length); 73 | 74 | /** 75 | * This function makes a CRC32 calculation on Length data bytes 76 | * 77 | * RETURN VALUE: 32 bit result of CRC calculation 78 | */ 79 | uint32_t CRC_CalculateCRC32(const uint8_t *Buffer, uint8_t Length); 80 | 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | 86 | 87 | #endif // CRC_H_INCLUDED 88 | -------------------------------------------------------------------------------- /src/GrIP/GrIP.h: -------------------------------------------------------------------------------- 1 | /* 2 | GrIP.h - GRBL over IP 3 | 4 | Copyright (c) 2018 Patrick F. 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | You should have received a copy of the GNU General Public License 16 | along with program. If not, see . 17 | */ 18 | #ifndef GRIP_H_INCLUDED 19 | #define GRIP_H_INCLUDED 20 | 21 | 22 | #include 23 | 24 | 25 | // Current protocol version 26 | #define GRIP_VERSION 1 27 | 28 | // Transmit/Receive buffer size - Do not exceed (GRIP_BUFFER_SIZE - 10) 29 | #define GRIP_BUFFER_SIZE 256 30 | #define GRIP_RX_NUM 3 31 | 32 | 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | 39 | /** 40 | * Available message types. 41 | * 42 | */ 43 | typedef enum 44 | { 45 | MSG_SYSTEM_CMD = 0, 46 | MSG_REALTIME_CMD = 1, 47 | MSG_DATA = 2, 48 | MSG_DATA_NO_RESPONSE = 3, 49 | MSG_NOTIFICATION = 4, 50 | MSG_RESPONSE = 5, 51 | MSG_ERROR = 6, 52 | MSG_MAX_NUM = 7 53 | } MessageType_e; 54 | 55 | 56 | /** 57 | * Return Types. 58 | * 59 | */ 60 | typedef enum 61 | { 62 | RET_OK = 0, 63 | RET_NOK = 1, 64 | RET_WRONG_VERSION = 2, 65 | RET_WRONG_CRC = 3, 66 | RET_WRONG_MAGIC = 4, 67 | RET_WRONG_PARAM = 5, 68 | RET_WRONG_TYPE = 6 69 | } ReturnType_e; 70 | 71 | 72 | /** 73 | * Types for response status. 74 | * 75 | */ 76 | typedef enum 77 | { 78 | RESPONSE_OK = 0, 79 | RESPONSE_WAIT = 1, 80 | RESPONSE_FAIL = 2 81 | } ResponseStatus_e; 82 | 83 | 84 | /** 85 | * GrIP Packet Header 86 | */ 87 | #pragma pack(push, 1) 88 | typedef struct 89 | { 90 | uint8_t Version; 91 | uint8_t MsgType; 92 | uint8_t ReturnCode; 93 | uint16_t Length; 94 | uint8_t CRC8; 95 | uint8_t Counter; 96 | } GrIP_PacketHeader_t; 97 | #pragma pack(pop) 98 | 99 | 100 | /** 101 | * GrIP Receive Packet 102 | */ 103 | typedef struct 104 | { 105 | GrIP_PacketHeader_t RX_Header; 106 | uint8_t isValid; 107 | uint8_t Data[GRIP_BUFFER_SIZE]; 108 | } RX_Packet_t; 109 | 110 | 111 | /** 112 | * Data struct. 113 | * Data: Pointer to data. 114 | * Length: Length of data in bytes. 115 | */ 116 | typedef struct 117 | { 118 | uint8_t *Data; 119 | uint16_t Length; 120 | } Pdu_t; 121 | 122 | 123 | /** 124 | * Initialize the module 125 | */ 126 | void GrIP_Init(void); 127 | 128 | /** 129 | * Transmit a message over GrIP 130 | */ 131 | uint8_t GrIP_Transmit(uint8_t MsgType, uint8_t ReturnCode, Pdu_t *data); 132 | 133 | /** 134 | * Returns the current response state 135 | */ 136 | uint8_t GrIP_ResponseStatus(void); 137 | 138 | /** 139 | * Get data if available 140 | */ 141 | uint8_t GrIP_Receive(RX_Packet_t *pData); 142 | 143 | /** 144 | * Continuously call this function to process RX messages 145 | */ 146 | void GrIP_Update(void); 147 | 148 | 149 | #ifdef __cplusplus 150 | } 151 | #endif 152 | 153 | 154 | #endif // GRIP_H_INCLUDED 155 | -------------------------------------------------------------------------------- /src/candle2.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2014-05-23T17:51:21 4 | # 5 | #------------------------------------------------- 6 | 7 | QT = core gui opengl serialport widgets network 8 | 9 | win32: { 10 | QT += winextras 11 | DEFINES += WINDOWS 12 | QMAKE_CFLAGS += -std=c11 13 | QMAKE_CXXFLAGS_DEBUG += -g3 -pg -std=c++14 14 | QMAKE_LFLAGS_DEBUG += -pg -lgmon 15 | } 16 | 17 | unix:!macx { 18 | DEFINES += UNIX #GL_GLEXT_PROTOTYPES 19 | QMAKE_LFLAGS += "-Wl,-rpath,\'\$$ORIGIN/libs\'" 20 | } 21 | 22 | contains(QT_CONFIG, opengles.) { 23 | warning("GL ES detected. VAO will be disabled.") 24 | DEFINES += GLES 25 | INSTALLS += target 26 | target.path = /home/pi 27 | } 28 | 29 | TARGET = Candle2 30 | TEMPLATE = app 31 | VERSION = 2.2.0 32 | RC_ICONS += images/candle.ico 33 | 34 | DEFINES += sNan=\"65536\" 35 | DEFINES += APP_VERSION=\\\"$$VERSION\\\" 36 | 37 | #TRANSLATIONS += translations/candle_en.ts translations/candle_ru.ts translations/candle_es.ts translations/candle_fr.ts translations/candle_pt.ts 38 | 39 | SOURCES += main.cpp\ 40 | frmmain.cpp \ 41 | frmsettings.cpp \ 42 | frmabout.cpp \ 43 | drawers/gcodedrawer.cpp \ 44 | drawers/heightmapborderdrawer.cpp \ 45 | drawers/heightmapgriddrawer.cpp \ 46 | drawers/heightmapinterpolationdrawer.cpp \ 47 | drawers/origindrawer.cpp \ 48 | drawers/shaderdrawable.cpp \ 49 | drawers/tooldrawer.cpp \ 50 | parser/arcproperties.cpp \ 51 | parser/gcodeparser.cpp \ 52 | parser/gcodepreprocessorutils.cpp \ 53 | parser/gcodeviewparse.cpp \ 54 | parser/linesegment.cpp \ 55 | parser/pointsegment.cpp \ 56 | tables/gcodetablemodel.cpp \ 57 | tables/heightmaptablemodel.cpp \ 58 | utils/profiles.cpp \ 59 | widgets/colorpicker.cpp \ 60 | widgets/combobox.cpp \ 61 | widgets/groupbox.cpp \ 62 | widgets/scrollarea.cpp \ 63 | widgets/styledtoolbutton.cpp \ 64 | widgets/widget.cpp \ 65 | widgets/glwidget.cpp \ 66 | widgets/slider.cpp \ 67 | widgets/sliderbox.cpp \ 68 | drawers/selectiondrawer.cpp \ 69 | widgets/comboboxkey.cpp \ 70 | protocol/grbl1_1.cpp \ 71 | interface/SerialInterface.cpp \ 72 | GrIP/CRC.c \ 73 | frmmain_heightmap.cpp \ 74 | frmmain_jogcontrol.cpp \ 75 | frmmain_processresponse.cpp \ 76 | frmmain_settings.cpp \ 77 | frmmain_util.cpp \ 78 | frmmain_event.cpp \ 79 | GrIP/GrIP.cpp 80 | 81 | HEADERS += frmmain.h \ 82 | frmsettings.h \ 83 | frmabout.h \ 84 | drawers/gcodedrawer.h \ 85 | drawers/heightmapborderdrawer.h \ 86 | drawers/heightmapgriddrawer.h \ 87 | drawers/heightmapinterpolationdrawer.h \ 88 | drawers/origindrawer.h \ 89 | drawers/shaderdrawable.h \ 90 | drawers/tooldrawer.h \ 91 | parser/arcproperties.h \ 92 | parser/gcodeparser.h \ 93 | parser/gcodepreprocessorutils.h \ 94 | parser/gcodeviewparse.h \ 95 | parser/linesegment.h \ 96 | parser/pointsegment.h \ 97 | tables/gcodetablemodel.h \ 98 | tables/heightmaptablemodel.h \ 99 | utils/interpolation.h \ 100 | utils/profiles.h \ 101 | utils/util.h \ 102 | widgets/colorpicker.h \ 103 | widgets/combobox.h \ 104 | widgets/groupbox.h \ 105 | widgets/scrollarea.h \ 106 | widgets/styledtoolbutton.h \ 107 | widgets/widget.h \ 108 | widgets/glwidget.h \ 109 | widgets/slider.h \ 110 | widgets/sliderbox.h \ 111 | drawers/selectiondrawer.h \ 112 | widgets/comboboxkey.h \ 113 | protocol/grbl1_1.h \ 114 | interface/SerialInterface.h \ 115 | GrIP/CRC.h \ 116 | GrIP/GrIP.h \ 117 | utils/safequeue.h 118 | 119 | FORMS += frmmain.ui \ 120 | frmsettings.ui \ 121 | frmabout.ui \ 122 | widgets/sliderbox.ui 123 | 124 | DEFINES += _USE_MATH_DEFINES 125 | 126 | RESOURCES += \ 127 | shaders.qrc \ 128 | images.qrc 129 | 130 | CONFIG += c++14 131 | -------------------------------------------------------------------------------- /src/drawers/gcodedrawer.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef GCODEDRAWER_H 5 | #define GCODEDRAWER_H 6 | 7 | #include 8 | #include 9 | #include "parser/linesegment.h" 10 | #include "parser/gcodeviewparse.h" 11 | #include "shaderdrawable.h" 12 | 13 | class GcodeDrawer : public QObject, public ShaderDrawable 14 | { 15 | Q_OBJECT 16 | public: 17 | enum GrayscaleCode { S, Z }; 18 | enum DrawMode { Vectors, Raster }; 19 | 20 | explicit GcodeDrawer(); 21 | 22 | void update(); 23 | void update(QList indexes); 24 | bool updateData(); 25 | 26 | QVector3D getSizes(); 27 | QVector3D getMinimumExtremes(); 28 | QVector3D getMaximumExtremes(); 29 | 30 | void setViewParser(GcodeViewParse* viewParser); 31 | GcodeViewParse* viewParser(); 32 | 33 | bool simplify() const; 34 | void setSimplify(bool simplify); 35 | 36 | double simplifyPrecision() const; 37 | void setSimplifyPrecision(double simplifyPrecision); 38 | 39 | bool geometryUpdated(); 40 | 41 | QColor colorNormal() const; 42 | void setColorNormal(const QColor &colorNormal); 43 | 44 | QColor colorHighlight() const; 45 | void setColorHighlight(const QColor &colorHighlight); 46 | 47 | QColor colorZMovement() const; 48 | void setColorZMovement(const QColor &colorZMovement); 49 | 50 | QColor colorDrawn() const; 51 | void setColorDrawn(const QColor &colorDrawn); 52 | 53 | QColor colorStart() const; 54 | void setColorStart(const QColor &colorStart); 55 | 56 | QColor colorEnd() const; 57 | void setColorEnd(const QColor &colorEnd); 58 | 59 | bool getIgnoreZ() const; 60 | void setIgnoreZ(bool ignoreZ); 61 | 62 | bool getGrayscaleSegments() const; 63 | void setGrayscaleSegments(bool grayscaleSegments); 64 | 65 | GrayscaleCode grayscaleCode() const; 66 | void setGrayscaleCode(const GrayscaleCode &grayscaleCode); 67 | 68 | int grayscaleMin() const; 69 | void setGrayscaleMin(int grayscaleMin); 70 | 71 | int grayscaleMax() const; 72 | void setGrayscaleMax(int grayscaleMax); 73 | 74 | DrawMode drawMode() const; 75 | void setDrawMode(const DrawMode &drawMode); 76 | 77 | signals: 78 | 79 | public slots: 80 | 81 | private slots: 82 | void onTimerVertexUpdate(); 83 | 84 | private: 85 | GcodeViewParse *m_viewParser; 86 | 87 | DrawMode m_drawMode; 88 | 89 | bool m_simplify; 90 | double m_simplifyPrecision; 91 | bool m_ignoreZ; 92 | bool m_grayscaleSegments; 93 | GrayscaleCode m_grayscaleCode; 94 | int m_grayscaleMin; 95 | int m_grayscaleMax; 96 | 97 | QColor m_colorNormal; 98 | QColor m_colorDrawn; 99 | QColor m_colorHighlight; 100 | QColor m_colorZMovement; 101 | QColor m_colorStart; 102 | QColor m_colorEnd; 103 | 104 | QTimer m_timerVertexUpdate; 105 | 106 | QImage m_image; 107 | QList m_indexes; 108 | bool m_geometryUpdated; 109 | 110 | bool prepareVectors(); 111 | bool updateVectors(); 112 | bool prepareRaster(); 113 | bool updateRaster(); 114 | 115 | int getSegmentType(LineSegment *segment); 116 | QVector3D getSegmentColorVector(LineSegment *segment); 117 | QColor getSegmentColor(LineSegment *segment); 118 | void setImagePixelColor(QImage &image, double x, double y, QRgb color) const; 119 | }; 120 | 121 | #endif // GCODEDRAWER_H 122 | -------------------------------------------------------------------------------- /src/drawers/heightmapborderdrawer.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "heightmapborderdrawer.h" 5 | 6 | HeightMapBorderDrawer::HeightMapBorderDrawer() 7 | { 8 | } 9 | 10 | QRectF HeightMapBorderDrawer::borderRect() const 11 | { 12 | return m_borderRect; 13 | } 14 | 15 | void HeightMapBorderDrawer::setBorderRect(const QRectF &borderRect) 16 | { 17 | m_borderRect = borderRect; 18 | update(); 19 | } 20 | 21 | bool HeightMapBorderDrawer::updateData() 22 | { 23 | m_lines = { 24 | {QVector3D(m_borderRect.x(), m_borderRect.y(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 25 | {QVector3D(m_borderRect.x(), m_borderRect.y() + m_borderRect.height(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 26 | {QVector3D(m_borderRect.x(), m_borderRect.y() + m_borderRect.height(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 27 | {QVector3D(m_borderRect.x() + m_borderRect.width(), m_borderRect.y() + m_borderRect.height(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 28 | {QVector3D(m_borderRect.x() + m_borderRect.width(), m_borderRect.y() + m_borderRect.height(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 29 | {QVector3D(m_borderRect.x() + m_borderRect.width(), m_borderRect.y(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 30 | {QVector3D(m_borderRect.x() + m_borderRect.width(), m_borderRect.y(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 31 | {QVector3D(m_borderRect.x(), m_borderRect.y(), 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 32 | }; 33 | return true; 34 | } 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/drawers/heightmapborderdrawer.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef HEIGHTMAPBORDERDRAWER_H 5 | #define HEIGHTMAPBORDERDRAWER_H 6 | 7 | #include 8 | #include "shaderdrawable.h" 9 | 10 | class HeightMapBorderDrawer : public ShaderDrawable 11 | { 12 | public: 13 | HeightMapBorderDrawer(); 14 | 15 | QRectF borderRect() const; 16 | void setBorderRect(const QRectF &borderRect); 17 | 18 | protected: 19 | bool updateData(); 20 | 21 | private: 22 | QRectF m_borderRect; 23 | }; 24 | 25 | #endif // HEIGHTMAPBORDERDRAWER_H 26 | -------------------------------------------------------------------------------- /src/drawers/heightmapgriddrawer.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "heightmapgriddrawer.h" 5 | 6 | HeightMapGridDrawer::HeightMapGridDrawer() 7 | { 8 | m_model = NULL; 9 | m_pointSize = 4; 10 | } 11 | 12 | bool HeightMapGridDrawer::updateData() 13 | { 14 | // Clear data 15 | m_lines.clear(); 16 | m_points.clear(); 17 | 18 | // Prepare vertex 19 | VertexData vertex; 20 | vertex.start = QVector3D(sNan, sNan, m_pointSize); 21 | 22 | // Calculate grid parameters 23 | int gridPointsX = m_model->columnCount(); 24 | int gridPointsY = m_model->rowCount(); 25 | 26 | double gridStepX = gridPointsX > 1 ? m_borderRect.width() / (gridPointsX - 1) : 0; 27 | double gridStepY = gridPointsY > 1 ? m_borderRect.height() / (gridPointsY - 1) : 0; 28 | 29 | // Probe path / dots 30 | for (int i = 0; i < gridPointsY; i++) { 31 | for (int j = 0; j < gridPointsX; j++) { 32 | if (m_model == NULL || qIsNaN(m_model->data(m_model->index(i, j), Qt::UserRole).toDouble())) { 33 | vertex.color = QVector3D(1.0, 0.6, 0.0); 34 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * i, m_zTop); 35 | m_lines.append(vertex); 36 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * i, m_zBottom); 37 | m_lines.append(vertex); 38 | } else { 39 | vertex.color = QVector3D(0.0, 0.0, 1.0); 40 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * i, m_model->data(m_model->index(i, j), Qt::UserRole).toDouble()); 41 | m_points.append(vertex); 42 | } 43 | } 44 | } 45 | 46 | // Horizontal grid lines 47 | vertex.color = QVector3D(0.0, 0.0, 1.0); 48 | for (int i = 0; i < gridPointsY; i++) { 49 | for (int j = 1; j < gridPointsX; j++) { 50 | if (qIsNaN(m_model->data(m_model->index(i, j), Qt::UserRole).toDouble())) continue; 51 | 52 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * (j - 1), m_borderRect.y() + gridStepY * i, m_model->data(m_model->index(i, j - 1), Qt::UserRole).toDouble()); 53 | m_lines.append(vertex); 54 | 55 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * i, m_model->data(m_model->index(i, j), Qt::UserRole).toDouble()); 56 | m_lines.append(vertex); 57 | } 58 | } 59 | 60 | // Vertical grid lines 61 | vertex.color = QVector3D(0.0, 0.0, 1.0); 62 | for (int j = 0; j < gridPointsX; j++) { 63 | for (int i = 1; i < gridPointsY; i++) { 64 | if (qIsNaN(m_model->data(m_model->index(i, j), Qt::UserRole).toDouble())) continue; 65 | 66 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * (i - 1), m_model->data(m_model->index(i - 1, j), Qt::UserRole).toDouble()); 67 | m_lines.append(vertex); 68 | 69 | vertex.position = QVector3D(m_borderRect.x() + gridStepX * j, m_borderRect.y() + gridStepY * i, m_model->data(m_model->index(i, j), Qt::UserRole).toDouble()); 70 | m_lines.append(vertex); 71 | } 72 | } 73 | 74 | return true; 75 | } 76 | 77 | QPointF HeightMapGridDrawer::gridSize() const 78 | { 79 | return m_gridSize; 80 | } 81 | 82 | void HeightMapGridDrawer::setGridSize(const QPointF &gridSize) 83 | { 84 | m_gridSize = gridSize; 85 | update(); 86 | } 87 | QRectF HeightMapGridDrawer::borderRect() const 88 | { 89 | return m_borderRect; 90 | } 91 | 92 | void HeightMapGridDrawer::setBorderRect(const QRectF &borderRect) 93 | { 94 | m_borderRect = borderRect; 95 | update(); 96 | } 97 | 98 | double HeightMapGridDrawer::zTop() const 99 | { 100 | return m_zTop; 101 | } 102 | 103 | void HeightMapGridDrawer::setZTop(double zTop) 104 | { 105 | m_zTop = zTop; 106 | update(); 107 | } 108 | double HeightMapGridDrawer::zBottom() const 109 | { 110 | return m_zBottom; 111 | } 112 | 113 | void HeightMapGridDrawer::setZBottom(double zBottom) 114 | { 115 | m_zBottom = zBottom; 116 | update(); 117 | } 118 | 119 | QAbstractTableModel *HeightMapGridDrawer::model() const 120 | { 121 | return m_model; 122 | } 123 | 124 | void HeightMapGridDrawer::setModel(QAbstractTableModel *model) 125 | { 126 | m_model = model; 127 | update(); 128 | } 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /src/drawers/heightmapgriddrawer.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef HEIGHTMAPGRIDDRAWER_H 5 | #define HEIGHTMAPGRIDDRAWER_H 6 | 7 | #include 8 | #include 9 | #include "shaderdrawable.h" 10 | 11 | class HeightMapGridDrawer : public ShaderDrawable 12 | { 13 | public: 14 | HeightMapGridDrawer(); 15 | 16 | QPointF gridSize() const; 17 | void setGridSize(const QPointF &gridSize); 18 | 19 | QRectF borderRect() const; 20 | void setBorderRect(const QRectF &borderRect); 21 | 22 | double zTop() const; 23 | void setZTop(double zTop); 24 | 25 | double zBottom() const; 26 | void setZBottom(double zBottom); 27 | 28 | QAbstractTableModel *model() const; 29 | void setModel(QAbstractTableModel *model); 30 | 31 | protected: 32 | bool updateData(); 33 | 34 | private: 35 | QPointF m_gridSize; 36 | QRectF m_borderRect; 37 | double m_zTop; 38 | double m_zBottom; 39 | QAbstractTableModel *m_model; 40 | }; 41 | 42 | #endif // HEIGHTMAPGRIDDRAWER_H 43 | -------------------------------------------------------------------------------- /src/drawers/heightmapinterpolationdrawer.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "heightmapinterpolationdrawer.h" 5 | 6 | HeightMapInterpolationDrawer::HeightMapInterpolationDrawer() 7 | { 8 | m_data = NULL; 9 | } 10 | 11 | bool HeightMapInterpolationDrawer::updateData() 12 | { 13 | // Check if data is present 14 | if (!m_data || m_data->count() == 0) { 15 | m_lines.clear(); 16 | return true; 17 | } 18 | 19 | QColor color; 20 | 21 | // Clear data 22 | m_lines.clear(); 23 | 24 | // Prepare vertex 25 | VertexData vertex; 26 | vertex.start = QVector3D(sNan, sNan, sNan); 27 | 28 | // Calculate grid parameters 29 | int interpolationPointsX = m_data->at(0).count(); 30 | int interpolationPointsY = m_data->count(); 31 | 32 | double interpolationStepX = interpolationPointsX > 1 ? m_borderRect.width() / (interpolationPointsX - 1) : 0; 33 | double interpolationStepY = interpolationPointsY > 1 ? m_borderRect.height() / (interpolationPointsY - 1) : 0; 34 | 35 | // Find min & max values for coloring 36 | double min = m_data->at(0).at(0); 37 | double max = min; 38 | 39 | for (int i = 0; i < interpolationPointsY; i++) { 40 | for (int j = 0; j < interpolationPointsX; j++) { 41 | min = Util::nMin(min, m_data->at(i).at(j)); 42 | max = Util::nMax(max, m_data->at(i).at(j)); 43 | } 44 | } 45 | 46 | // Horizontal lines 47 | for (int i = 0; i < interpolationPointsY; i++) { 48 | for (int j = 1; j < interpolationPointsX; j++) { 49 | if (qIsNaN(m_data->at(i).at(j))) continue; 50 | color.setHsvF(0.67 * (max - m_data->at(i).at(j - 1)) / (max - min), 1.0, 1.0); 51 | vertex.color = QVector3D(color.redF(), color.greenF(), color.blueF()); 52 | 53 | vertex.position = QVector3D(m_borderRect.x() + interpolationStepX * (j - 1), m_borderRect.y() + interpolationStepY * i, m_data->at(i).at(j - 1)); 54 | m_lines.append(vertex); 55 | 56 | color.setHsvF(0.67 * (max - m_data->at(i).at(j)) / (max - min), 1.0, 1.0); 57 | vertex.color = QVector3D(color.redF(), color.greenF(), color.blueF()); 58 | 59 | vertex.position = QVector3D(m_borderRect.x() + interpolationStepX * j, m_borderRect.y() + interpolationStepY * i, m_data->at(i).at(j)); 60 | m_lines.append(vertex); 61 | } 62 | } 63 | 64 | // Vertical lines 65 | for (int j = 0; j < interpolationPointsX; j++) { 66 | for (int i = 1; i < interpolationPointsY; i++) { 67 | if (qIsNaN(m_data->at(i).at(j))) continue; 68 | color.setHsvF(0.67 * (max - m_data->at(i - 1).at(j)) / (max - min), 1.0, 1.0); 69 | vertex.color = QVector3D(color.redF(), color.greenF(), color.blueF()); 70 | 71 | vertex.position = QVector3D(m_borderRect.x() + interpolationStepX * j, m_borderRect.y() + interpolationStepY * (i - 1), m_data->at(i - 1).at(j)); 72 | m_lines.append(vertex); 73 | 74 | color.setHsvF(0.67 * (max - m_data->at(i).at(j)) / (max - min), 1.0, 1.0); 75 | vertex.color = QVector3D(color.redF(), color.greenF(), color.blueF()); 76 | 77 | vertex.position = QVector3D(m_borderRect.x() + interpolationStepX * j, m_borderRect.y() + interpolationStepY * i, m_data->at(i).at(j)); 78 | m_lines.append(vertex); 79 | } 80 | } 81 | 82 | return true; 83 | } 84 | 85 | QVector > *HeightMapInterpolationDrawer::data() const 86 | { 87 | return m_data; 88 | } 89 | 90 | void HeightMapInterpolationDrawer::setData(QVector > *data) 91 | { 92 | m_data = data; 93 | update(); 94 | } 95 | QRectF HeightMapInterpolationDrawer::borderRect() const 96 | { 97 | return m_borderRect; 98 | } 99 | 100 | void HeightMapInterpolationDrawer::setBorderRect(const QRectF &borderRect) 101 | { 102 | m_borderRect = borderRect; 103 | } 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /src/drawers/heightmapinterpolationdrawer.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef HEIGHTMAPINTERPOLATIONDRAWER_H 5 | #define HEIGHTMAPINTERPOLATIONDRAWER_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "shaderdrawable.h" 12 | #include "utils/util.h" 13 | 14 | class HeightMapInterpolationDrawer : public ShaderDrawable 15 | { 16 | public: 17 | explicit HeightMapInterpolationDrawer(); 18 | 19 | QVector > *data() const; 20 | void setData(QVector > *data); 21 | 22 | QRectF borderRect() const; 23 | void setBorderRect(const QRectF &borderRect); 24 | 25 | protected: 26 | bool updateData(); 27 | 28 | private: 29 | QRectF m_borderRect; 30 | double m_gridSize; 31 | QVector> *m_data; 32 | double Min(double v1, double v2); 33 | double Max(double v1, double v2); 34 | }; 35 | 36 | #endif // HEIGHTMAPINTERPOLATIONDRAWER_H 37 | -------------------------------------------------------------------------------- /src/drawers/origindrawer.cpp: -------------------------------------------------------------------------------- 1 | #include "origindrawer.h" 2 | 3 | OriginDrawer::OriginDrawer() 4 | { 5 | } 6 | 7 | bool OriginDrawer::updateData() 8 | { 9 | m_lines = { 10 | // X-axis 11 | {QVector3D(0, 0, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 12 | {QVector3D(9, 0, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 13 | {QVector3D(10, 0, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 14 | {QVector3D(8, 0.5, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 15 | {QVector3D(8, 0.5, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 16 | {QVector3D(8, -0.5, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 17 | {QVector3D(8, -0.5, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 18 | {QVector3D(10, 0, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 19 | 20 | // Y-axis 21 | {QVector3D(0, 0, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 22 | {QVector3D(0, 9, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 23 | {QVector3D(0, 10, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 24 | {QVector3D(0.5, 8, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 25 | {QVector3D(0.5, 8, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 26 | {QVector3D(-0.5, 8, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 27 | {QVector3D(-0.5, 8, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 28 | {QVector3D(0, 10, 0), QVector3D(0.0, 1.0, 0.0), QVector3D(sNan, sNan, sNan)}, 29 | 30 | // Z-axis 31 | {QVector3D(0, 0, 0), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 32 | {QVector3D(0, 0, 9), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 33 | {QVector3D(0, 0, 10), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 34 | {QVector3D(0.5, 0, 8), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 35 | {QVector3D(0.5, 0, 8), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 36 | {QVector3D(-0.5, 0, 8), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 37 | {QVector3D(-0.5, 0, 8), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 38 | {QVector3D(0, 0, 10), QVector3D(0.0, 0.0, 1.0), QVector3D(sNan, sNan, sNan)}, 39 | 40 | // 2x2 rect 41 | {QVector3D(1, 1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 42 | {QVector3D(-1, 1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 43 | {QVector3D(-1, 1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 44 | {QVector3D(-1, -1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 45 | {QVector3D(-1, -1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 46 | {QVector3D(1, -1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 47 | {QVector3D(1, -1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 48 | {QVector3D(1, 1, 0), QVector3D(1.0, 0.0, 0.0), QVector3D(sNan, sNan, sNan)}, 49 | }; 50 | return true; 51 | } 52 | -------------------------------------------------------------------------------- /src/drawers/origindrawer.h: -------------------------------------------------------------------------------- 1 | #ifndef ORIGINDRAWER_H 2 | #define ORIGINDRAWER_H 3 | 4 | #include "shaderdrawable.h" 5 | 6 | class OriginDrawer : public ShaderDrawable 7 | { 8 | public: 9 | OriginDrawer(); 10 | 11 | protected: 12 | bool updateData(); 13 | }; 14 | 15 | #endif // ORIGINDRAWER_H 16 | -------------------------------------------------------------------------------- /src/drawers/selectiondrawer.cpp: -------------------------------------------------------------------------------- 1 | #include "selectiondrawer.h" 2 | 3 | SelectionDrawer::SelectionDrawer() 4 | { 5 | m_endPosition = QVector3D(sNan, sNan, sNan); 6 | m_pointSize = 6.0; 7 | } 8 | 9 | bool SelectionDrawer::updateData() 10 | { 11 | m_points.clear(); 12 | 13 | VertexData vertex; 14 | vertex.color = Util::colorToVector(m_color); 15 | vertex.position = m_endPosition; 16 | vertex.start = QVector3D(sNan, sNan, m_pointSize); 17 | m_points.append(vertex); 18 | 19 | return true; 20 | } 21 | 22 | QVector3D SelectionDrawer::endPosition() const 23 | { 24 | return m_endPosition; 25 | } 26 | 27 | void SelectionDrawer::setEndPosition(const QVector3D &endPosition) 28 | { 29 | m_endPosition = endPosition; 30 | } 31 | 32 | QColor SelectionDrawer::color() const 33 | { 34 | return m_color; 35 | } 36 | 37 | void SelectionDrawer::setColor(const QColor &color) 38 | { 39 | m_color = color; 40 | } 41 | 42 | QVector3D SelectionDrawer::startPosition() const 43 | { 44 | return m_startPosition; 45 | } 46 | 47 | void SelectionDrawer::setStartPosition(const QVector3D &startPosition) 48 | { 49 | m_startPosition = startPosition; 50 | } 51 | -------------------------------------------------------------------------------- /src/drawers/selectiondrawer.h: -------------------------------------------------------------------------------- 1 | #ifndef SELECTIONDRAWER_H 2 | #define SELECTIONDRAWER_H 3 | 4 | #include "shaderdrawable.h" 5 | 6 | class SelectionDrawer : public ShaderDrawable 7 | { 8 | public: 9 | SelectionDrawer(); 10 | 11 | QVector3D startPosition() const; 12 | void setStartPosition(const QVector3D &startPosition); 13 | 14 | QColor color() const; 15 | void setColor(const QColor &color); 16 | 17 | QVector3D endPosition() const; 18 | void setEndPosition(const QVector3D &endPosition); 19 | 20 | protected: 21 | bool updateData(); 22 | 23 | private: 24 | QVector3D m_startPosition; 25 | QVector3D m_endPosition; 26 | 27 | QColor m_color; 28 | }; 29 | 30 | #endif // SELECTIONDRAWER_H 31 | -------------------------------------------------------------------------------- /src/drawers/shaderdrawable.h: -------------------------------------------------------------------------------- 1 | #ifndef SHADERDRAWABLE_H 2 | #define SHADERDRAWABLE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "utils/util.h" 11 | 12 | struct VertexData 13 | { 14 | QVector3D position; 15 | QVector3D color; 16 | QVector3D start; 17 | }; 18 | 19 | class ShaderDrawable : protected QOpenGLFunctions 20 | { 21 | public: 22 | explicit ShaderDrawable(); 23 | ~ShaderDrawable(); 24 | void update(); 25 | void draw(QOpenGLShaderProgram *shaderProgram); 26 | 27 | bool needsUpdateGeometry() const; 28 | void updateGeometry(QOpenGLShaderProgram *shaderProgram = 0); 29 | 30 | virtual QVector3D getSizes(); 31 | virtual QVector3D getMinimumExtremes(); 32 | virtual QVector3D getMaximumExtremes(); 33 | virtual int getVertexCount(); 34 | 35 | double lineWidth() const; 36 | void setLineWidth(double lineWidth); 37 | 38 | bool visible() const; 39 | void setVisible(bool visible); 40 | 41 | double pointSize() const; 42 | void setPointSize(double pointSize); 43 | 44 | signals: 45 | 46 | public slots: 47 | 48 | protected: 49 | double m_lineWidth; 50 | double m_pointSize; 51 | bool m_visible; 52 | QVector m_lines; 53 | QVector m_points; 54 | QVector m_triangles; 55 | QOpenGLTexture *m_texture; 56 | 57 | QOpenGLBuffer m_vbo; // Protected for direct vbo access 58 | 59 | virtual bool updateData(); 60 | void init(); 61 | 62 | private: 63 | QOpenGLVertexArrayObject m_vao; 64 | 65 | bool m_needsUpdateGeometry; 66 | }; 67 | 68 | #endif // SHADERDRAWABLE_H 69 | -------------------------------------------------------------------------------- /src/drawers/tooldrawer.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "tooldrawer.h" 5 | 6 | ToolDrawer::ToolDrawer() 7 | { 8 | m_toolDiameter = 3; 9 | m_toolLength = 15; 10 | m_toolPosition = QVector3D(0, 0, 0); 11 | m_rotationAngle = 0; 12 | } 13 | 14 | bool ToolDrawer::updateData() 15 | { 16 | const int arcs = 4; 17 | 18 | // Clear data 19 | m_lines.clear(); 20 | m_points.clear(); 21 | 22 | // Prepare vertex 23 | VertexData vertex; 24 | vertex.color = Util::colorToVector(m_color);//QVector3D(1.0, 0.6, 0.0); 25 | vertex.start = QVector3D(sNan, sNan, sNan); 26 | 27 | // Draw lines 28 | for (int i = 0; i < arcs; i++) { 29 | double x = m_toolPosition.x() + m_toolDiameter / 2 * cos(m_rotationAngle / 180 * M_PI + (2 * M_PI / arcs) * i); 30 | double y = m_toolPosition.y() + m_toolDiameter / 2 * sin(m_rotationAngle / 180 * M_PI + (2 * M_PI / arcs) * i); 31 | 32 | // Side lines 33 | vertex.position = QVector3D(x, y, m_toolPosition.z() + m_endLength); 34 | m_lines.append(vertex); 35 | vertex.position = QVector3D(x, y, m_toolPosition.z() + m_toolLength); 36 | m_lines.append(vertex); 37 | 38 | // Bottom lines 39 | vertex.position = QVector3D(m_toolPosition.x(), m_toolPosition.y(), m_toolPosition.z()); 40 | m_lines.append(vertex); 41 | vertex.position = QVector3D(x, y, m_toolPosition.z() + m_endLength); 42 | m_lines.append(vertex); 43 | 44 | // Top lines 45 | vertex.position = QVector3D(m_toolPosition.x(), m_toolPosition.y(), m_toolPosition.z() + m_toolLength); 46 | m_lines.append(vertex); 47 | vertex.position = QVector3D(x, y, m_toolPosition.z() + m_toolLength); 48 | m_lines.append(vertex); 49 | 50 | // Zero Z lines 51 | vertex.position = QVector3D(m_toolPosition.x(), m_toolPosition.y(), 0); 52 | m_lines.append(vertex); 53 | vertex.position = QVector3D(x, y, 0); 54 | m_lines.append(vertex); 55 | } 56 | 57 | // Draw circles 58 | // Bottom 59 | m_lines += createCircle(QVector3D(m_toolPosition.x(), m_toolPosition.y(), m_toolPosition.z() + m_endLength), 60 | m_toolDiameter / 2, 20, vertex.color); 61 | 62 | // Top 63 | m_lines += createCircle(QVector3D(m_toolPosition.x(), m_toolPosition.y(), m_toolPosition.z() + m_toolLength), 64 | m_toolDiameter / 2, 20, vertex.color); 65 | 66 | // Zero Z circle 67 | if (m_endLength == 0) { 68 | m_lines += createCircle(QVector3D(m_toolPosition.x(), m_toolPosition.y(), 0), 69 | m_toolDiameter / 2, 20, vertex.color); 70 | } 71 | 72 | return true; 73 | } 74 | QColor ToolDrawer::color() const 75 | { 76 | return m_color; 77 | } 78 | 79 | void ToolDrawer::setColor(const QColor &color) 80 | { 81 | m_color = color; 82 | } 83 | 84 | 85 | QVector ToolDrawer::createCircle(QVector3D center, double radius, int arcs, QVector3D color) 86 | { 87 | // Vertices 88 | QVector circle; 89 | 90 | // Prepare vertex 91 | VertexData vertex; 92 | vertex.color = color; 93 | vertex.start = QVector3D(sNan, sNan, sNan); 94 | 95 | // Create line loop 96 | for (int i = 0; i <= arcs; i++) { 97 | double angle = 2 * M_PI * i / arcs; 98 | double x = center.x() + radius * cos(angle); 99 | double y = center.y() + radius * sin(angle); 100 | 101 | if (i > 1) { 102 | circle.append(circle.last()); 103 | } 104 | else if (i == arcs) circle.append(circle.first()); 105 | 106 | vertex.position = QVector3D(x, y, center.z()); 107 | circle.append(vertex); 108 | } 109 | 110 | return circle; 111 | } 112 | 113 | double ToolDrawer::toolDiameter() const 114 | { 115 | return m_toolDiameter; 116 | } 117 | 118 | void ToolDrawer::setToolDiameter(double toolDiameter) 119 | { 120 | if (m_toolDiameter != toolDiameter) { 121 | m_toolDiameter = toolDiameter; 122 | update(); 123 | } 124 | } 125 | double ToolDrawer::toolLength() const 126 | { 127 | return m_toolLength; 128 | } 129 | 130 | void ToolDrawer::setToolLength(double toolLength) 131 | { 132 | if (m_toolLength != toolLength) { 133 | m_toolLength = toolLength; 134 | update(); 135 | } 136 | } 137 | QVector3D ToolDrawer::toolPosition() const 138 | { 139 | return m_toolPosition; 140 | } 141 | 142 | void ToolDrawer::setToolPosition(const QVector3D &toolPosition) 143 | { 144 | if (m_toolPosition != toolPosition) { 145 | m_toolPosition = toolPosition; 146 | update(); 147 | } 148 | } 149 | double ToolDrawer::rotationAngle() const 150 | { 151 | return m_rotationAngle; 152 | } 153 | 154 | void ToolDrawer::setRotationAngle(double rotationAngle) 155 | { 156 | if (m_rotationAngle != rotationAngle) { 157 | m_rotationAngle = rotationAngle; 158 | update(); 159 | } 160 | } 161 | 162 | void ToolDrawer::rotate(double angle) 163 | { 164 | setRotationAngle(normalizeAngle(m_rotationAngle + angle)); 165 | } 166 | 167 | double ToolDrawer::toolAngle() const 168 | { 169 | return m_toolAngle; 170 | } 171 | 172 | void ToolDrawer::setToolAngle(double toolAngle) 173 | { 174 | if (m_toolAngle != toolAngle) { 175 | m_toolAngle = toolAngle; 176 | 177 | m_endLength = m_toolAngle > 0 && m_toolAngle < 180 ? m_toolDiameter / 2 / tan(m_toolAngle / 180 * M_PI / 2) : 0; 178 | if (m_toolLength < m_endLength) m_toolLength = m_endLength; 179 | 180 | update(); 181 | } 182 | } 183 | 184 | double ToolDrawer::normalizeAngle(double angle) 185 | { 186 | while (angle < 0) angle += 360; 187 | while (angle > 360) angle -= 360; 188 | 189 | return angle; 190 | } 191 | -------------------------------------------------------------------------------- /src/drawers/tooldrawer.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef TOOLDRAWER_H 5 | #define TOOLDRAWER_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "shaderdrawable.h" 12 | 13 | class ToolDrawer : public ShaderDrawable 14 | { 15 | public: 16 | explicit ToolDrawer(); 17 | 18 | double toolDiameter() const; 19 | void setToolDiameter(double toolDiameter); 20 | 21 | double toolLength() const; 22 | void setToolLength(double toolLength); 23 | 24 | QVector3D toolPosition() const; 25 | void setToolPosition(const QVector3D &toolPosition); 26 | 27 | double rotationAngle() const; 28 | void setRotationAngle(double rotationAngle); 29 | void rotate(double angle); 30 | 31 | double toolAngle() const; 32 | void setToolAngle(double toolAngle); 33 | 34 | QColor color() const; 35 | void setColor(const QColor &color); 36 | 37 | signals: 38 | 39 | public slots: 40 | 41 | protected: 42 | bool updateData(); 43 | 44 | private: 45 | double m_toolDiameter; 46 | double m_toolLength; 47 | double m_endLength; 48 | QVector3D m_toolPosition; 49 | double m_rotationAngle; 50 | double m_toolAngle; 51 | QColor m_color; 52 | 53 | double normalizeAngle(double angle); 54 | QVector createCircle(QVector3D center, double radius, int arcs, QVector3D color); 55 | }; 56 | 57 | #endif // TOOLDRAWER_H 58 | -------------------------------------------------------------------------------- /src/fonts.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | fonts/segoeui.ttf 4 | fonts/tahoma.ttf 5 | fonts/Ubuntu-R.ttf 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/frmabout.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include 5 | #include "frmabout.h" 6 | #include "ui_frmabout.h" 7 | 8 | frmAbout::frmAbout(QWidget *parent) : 9 | QDialog(parent), 10 | ui(new Ui::frmAbout) 11 | { 12 | ui->setupUi(this); 13 | 14 | ui->lblAbout->setText(ui->lblAbout->text().arg(qApp->applicationVersion())); 15 | 16 | QFile file(qApp->applicationDirPath() + "/LICENSE"); 17 | 18 | if (file.open(QIODevice::ReadOnly)) { 19 | ui->txtLicense->setPlainText(file.readAll()); 20 | } 21 | } 22 | 23 | frmAbout::~frmAbout() 24 | { 25 | delete ui; 26 | } 27 | 28 | void frmAbout::on_cmdOk_clicked() 29 | { 30 | this->hide(); 31 | } 32 | 33 | void frmAbout::on_lblAbout_linkActivated(const QString &link) 34 | { 35 | QDesktopServices::openUrl(link); 36 | } 37 | -------------------------------------------------------------------------------- /src/frmabout.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef FRMABOUT_H 5 | #define FRMABOUT_H 6 | 7 | #include 8 | 9 | namespace Ui { 10 | class frmAbout; 11 | } 12 | 13 | class frmAbout : public QDialog 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit frmAbout(QWidget *parent = 0); 19 | ~frmAbout(); 20 | 21 | private slots: 22 | void on_cmdOk_clicked(); 23 | 24 | void on_lblAbout_linkActivated(const QString &link); 25 | 26 | private: 27 | Ui::frmAbout *ui; 28 | }; 29 | 30 | #endif // FRMABOUT_H 31 | -------------------------------------------------------------------------------- /src/frmabout.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | frmAbout 4 | 5 | 6 | 7 | 0 8 | 0 9 | 431 10 | 500 11 | 12 | 13 | 14 | About 15 | 16 | 17 | QWidget { 18 | font-size: 9pt; 19 | } 20 | 21 | 22 | 23 | 9 24 | 25 | 26 | 9 27 | 28 | 29 | 9 30 | 31 | 32 | 9 33 | 34 | 35 | 36 | 37 | 14 38 | 39 | 40 | 41 | 42 | 43 | 100 44 | 100 45 | 46 | 47 | 48 | image: url(:/images/candle_256.png); 49 | 50 | 51 | QFrame::StyledPanel 52 | 53 | 54 | QFrame::Raised 55 | 56 | 57 | 58 | 59 | 60 | 61 | <html><head><title>About</title></head><body><p>Candle 2<br/>Version: 2.6<br/>License: GNU GENERAL PUBLIC LICENSE<br/>© 2015-2016 Hayrullin Denis Ravilevich<br/>© 2018-2024 Patrick F.</p><p>Visit: <a href="https://github.com/Schildkroet/Candle2/"><span style=" text-decoration: underline; color:#0000ff;">https://github.com/Schildkroet/Candle2/</span></a></p></body></html> 62 | 63 | 64 | Qt::AutoText 65 | 66 | 67 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 68 | 69 | 70 | 71 | 72 | 73 | 74 | Qt::Horizontal 75 | 76 | 77 | 78 | 40 79 | 20 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | <html><head/><body><p><span style=" font-weight:600;">The program is provided AS IS without any guarantees or warranty. Use at your own risk.</span></p></body></html> 90 | 91 | 92 | true 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 9 101 | 102 | 103 | 104 | true 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | Qt::Horizontal 114 | 115 | 116 | 117 | 40 118 | 20 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | OK 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/images.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/search_for_home2.png 4 | images/search_for_z.png 5 | images/safe_z.png 6 | images/axis_zero.png 7 | images/axis_return.png 8 | images/restart.png 9 | images/handle_horizontal.png 10 | images/handle_vertical.png 11 | images/unlock.png 12 | images/1401562699_icon-arrow-up-b.png 13 | images/1401562699_icon-arrow-down-b.png 14 | images/1401562173_chevron-down.png 15 | images/1401562173_chevron-up.png 16 | images/1401562173_chevron-right.png 17 | images/1401561986_chevron-left.png 18 | images/zero_z.png 19 | images/cutter.png 20 | images/handle2s.png 21 | images/handle2sh.png 22 | images/cube.png 23 | images/fit_1.png 24 | images/send_1.png 25 | images/erase_1.png 26 | images/cubeFront.png 27 | images/cubeLeft.png 28 | images/cubeTop.png 29 | images/icon3png.png 30 | images/expand.png 31 | images/collapse.png 32 | images/collapse_disabled.png 33 | images/expand_disabled.png 34 | images/small_arrow.png 35 | images/shadow.png 36 | images/handle_small.png 37 | images/guard.png 38 | images/origin.png 39 | images/candle_256.png 40 | images/run.png 41 | images/num1.png 42 | images/num2.png 43 | images/num3.png 44 | images/num4.png 45 | images/handle2s1.png 46 | images/brake.png 47 | images/home.svg 48 | images/play.png 49 | images/stop.png 50 | images/pause.png 51 | images/home.png 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/images/1401561986_chevron-left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401561986_chevron-left.png -------------------------------------------------------------------------------- /src/images/1401562173_chevron-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401562173_chevron-down.png -------------------------------------------------------------------------------- /src/images/1401562173_chevron-right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401562173_chevron-right.png -------------------------------------------------------------------------------- /src/images/1401562173_chevron-up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401562173_chevron-up.png -------------------------------------------------------------------------------- /src/images/1401562699_icon-arrow-down-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401562699_icon-arrow-down-b.png -------------------------------------------------------------------------------- /src/images/1401562699_icon-arrow-up-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/1401562699_icon-arrow-up-b.png -------------------------------------------------------------------------------- /src/images/axis_return.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/axis_return.png -------------------------------------------------------------------------------- /src/images/axis_zero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/axis_zero.png -------------------------------------------------------------------------------- /src/images/axis_zero.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 30 | 35 | 36 | 43 | 48 | 49 | 56 | 61 | 62 | 69 | 74 | 75 | 76 | 105 | 113 | 114 | 116 | 117 | 119 | image/svg+xml 120 | 122 | 123 | 124 | 125 | 126 | 131 | 134 | 137 | 144 | Ø 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /src/images/brake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/brake.png -------------------------------------------------------------------------------- /src/images/candle.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/candle.ico -------------------------------------------------------------------------------- /src/images/candle_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/candle_16.png -------------------------------------------------------------------------------- /src/images/candle_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/candle_20.png -------------------------------------------------------------------------------- /src/images/candle_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/candle_256.png -------------------------------------------------------------------------------- /src/images/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/collapse.png -------------------------------------------------------------------------------- /src/images/collapse_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/collapse_disabled.png -------------------------------------------------------------------------------- /src/images/cube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cube.png -------------------------------------------------------------------------------- /src/images/cubeFront.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cubeFront.png -------------------------------------------------------------------------------- /src/images/cubeLeft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cubeLeft.png -------------------------------------------------------------------------------- /src/images/cubeTop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cubeTop.png -------------------------------------------------------------------------------- /src/images/cutter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cutter.png -------------------------------------------------------------------------------- /src/images/cutter1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/cutter1.ico -------------------------------------------------------------------------------- /src/images/erase_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/erase_1.png -------------------------------------------------------------------------------- /src/images/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/expand.png -------------------------------------------------------------------------------- /src/images/expand_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/expand_disabled.png -------------------------------------------------------------------------------- /src/images/fit_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/fit_1.png -------------------------------------------------------------------------------- /src/images/g7567.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/g7567.png -------------------------------------------------------------------------------- /src/images/grblControl1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/grblControl1.ico -------------------------------------------------------------------------------- /src/images/grblControl2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/grblControl2.ico -------------------------------------------------------------------------------- /src/images/guard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/guard.png -------------------------------------------------------------------------------- /src/images/guard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 54 | 62 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 83 | 86 | 92 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /src/images/handle2s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle2s.png -------------------------------------------------------------------------------- /src/images/handle2s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle2s1.png -------------------------------------------------------------------------------- /src/images/handle2sh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle2sh.png -------------------------------------------------------------------------------- /src/images/handle_horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle_horizontal.png -------------------------------------------------------------------------------- /src/images/handle_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle_small.png -------------------------------------------------------------------------------- /src/images/handle_vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/handle_vertical.png -------------------------------------------------------------------------------- /src/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/home.png -------------------------------------------------------------------------------- /src/images/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 52 | 60 | 61 | 63 | 64 | 66 | image/svg+xml 67 | 69 | 70 | 71 | 72 | 73 | 78 | 81 | 84 | 91 | 97 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/icon.png -------------------------------------------------------------------------------- /src/images/icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/icon1.png -------------------------------------------------------------------------------- /src/images/icon3_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/icon3_16.png -------------------------------------------------------------------------------- /src/images/icon3_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/icon3_20.png -------------------------------------------------------------------------------- /src/images/icon3png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/icon3png.png -------------------------------------------------------------------------------- /src/images/laser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 54 | 62 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 83 | 86 | 95 | 100 | 105 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/images/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/list.png -------------------------------------------------------------------------------- /src/images/list_collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/list_collapsed.png -------------------------------------------------------------------------------- /src/images/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu.png -------------------------------------------------------------------------------- /src/images/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 42 | 50 | 51 | 53 | 54 | 56 | image/svg+xml 57 | 59 | 60 | 61 | 62 | 67 | 73 | 79 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/images/menu_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu_13.png -------------------------------------------------------------------------------- /src/images/menu_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu_16.png -------------------------------------------------------------------------------- /src/images/menu_collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu_collapse.png -------------------------------------------------------------------------------- /src/images/menu_collapse_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu_collapse_13.png -------------------------------------------------------------------------------- /src/images/menu_collapse_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/menu_collapse_16.png -------------------------------------------------------------------------------- /src/images/num1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/num1.png -------------------------------------------------------------------------------- /src/images/num1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 44 | 52 | 53 | 55 | 56 | 58 | image/svg+xml 59 | 61 | 62 | 63 | 64 | 65 | 70 | 80 | 88 | 4 100 | 101 | 102 | -------------------------------------------------------------------------------- /src/images/num2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/num2.png -------------------------------------------------------------------------------- /src/images/num3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/num3.png -------------------------------------------------------------------------------- /src/images/num4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/num4.png -------------------------------------------------------------------------------- /src/images/origin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/origin.png -------------------------------------------------------------------------------- /src/images/origin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 54 | 62 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 83 | 86 | 95 | 100 | 105 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/pause.png -------------------------------------------------------------------------------- /src/images/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/play.png -------------------------------------------------------------------------------- /src/images/restart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/restart.png -------------------------------------------------------------------------------- /src/images/run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/run.png -------------------------------------------------------------------------------- /src/images/run.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 54 | 62 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 83 | 86 | 96 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/images/safe_z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/safe_z.png -------------------------------------------------------------------------------- /src/images/safe_z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 52 | 60 | 61 | 63 | 64 | 66 | image/svg+xml 67 | 69 | 70 | 71 | 72 | 73 | 78 | 81 | 84 | 89 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/images/search_for_home2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/search_for_home2.png -------------------------------------------------------------------------------- /src/images/search_for_z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/search_for_z.png -------------------------------------------------------------------------------- /src/images/search_home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 52 | 60 | 61 | 63 | 64 | 66 | image/svg+xml 67 | 69 | 70 | 71 | 72 | 73 | 78 | 81 | 84 | 96 | 106 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /src/images/search_z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 52 | 60 | 61 | 63 | 64 | 66 | image/svg+xml 67 | 69 | 70 | 71 | 72 | 73 | 78 | 81 | 84 | 96 | 106 | 112 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/images/send_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/send_1.png -------------------------------------------------------------------------------- /src/images/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/shadow.png -------------------------------------------------------------------------------- /src/images/small_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/small_arrow.png -------------------------------------------------------------------------------- /src/images/small_arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 39 | 41 | 42 | 44 | image/svg+xml 45 | 47 | 48 | 49 | 50 | 51 | 56 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/images/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/stop.png -------------------------------------------------------------------------------- /src/images/unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/unlock.png -------------------------------------------------------------------------------- /src/images/zero_z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/images/zero_z.png -------------------------------------------------------------------------------- /src/images/zero_z.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 52 | 60 | 61 | 63 | 64 | 66 | image/svg+xml 67 | 69 | 70 | 71 | 72 | 73 | 78 | 81 | 84 | 89 | 95 | Ø 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/interface/SerialInterface.cpp: -------------------------------------------------------------------------------- 1 | #include "SerialInterface.h" 2 | 3 | 4 | QSerialPort m_serialPort; 5 | QTcpSocket m_tcpSocket; 6 | Interface_e m_Interface; 7 | int m_Protocol; 8 | bool m_SocketOpen; 9 | 10 | QString m_ip; 11 | qint32 m_port; 12 | 13 | 14 | void SerialIf_Init() 15 | { 16 | // Setup serial port 17 | m_serialPort.setParity(QSerialPort::NoParity); 18 | m_serialPort.setDataBits(QSerialPort::Data8); 19 | m_serialPort.setFlowControl(QSerialPort::NoFlowControl); 20 | m_serialPort.setStopBits(QSerialPort::OneStop); 21 | 22 | m_Protocol = 0; 23 | m_SocketOpen = false; 24 | } 25 | 26 | void SerialIf_DeInit() 27 | { 28 | if(m_serialPort.isOpen()) 29 | { 30 | m_serialPort.close(); 31 | } 32 | 33 | if(m_tcpSocket.isOpen()) 34 | { 35 | m_tcpSocket.close(); 36 | m_SocketOpen = false; 37 | } 38 | } 39 | 40 | bool SerialIf_OpenSerial(int protocol, QString portname, qint32 baud) 41 | { 42 | m_serialPort.setPortName(portname); 43 | m_serialPort.setBaudRate(baud); 44 | 45 | m_Interface = IF_SERIAL; 46 | m_Protocol = protocol; 47 | 48 | return m_serialPort.open(QIODevice::ReadWrite); 49 | } 50 | 51 | bool SerialIf_OpenEth(QString ip, qint32 port) 52 | { 53 | m_Interface = IF_ETHERNET; 54 | 55 | if(m_tcpSocket.isOpen()) 56 | { 57 | // Close if already open 58 | m_tcpSocket.close(); 59 | } 60 | 61 | m_ip = ip; 62 | m_port = port; 63 | 64 | m_tcpSocket.connectToHost(ip, port); 65 | 66 | m_SocketOpen = m_tcpSocket.waitForConnected(3000); 67 | 68 | return m_SocketOpen; 69 | } 70 | 71 | void SerialIf_Close() 72 | { 73 | if(m_serialPort.isOpen()) 74 | { 75 | m_serialPort.close(); 76 | } 77 | 78 | if(m_tcpSocket.isOpen()) 79 | { 80 | m_tcpSocket.close(); 81 | m_SocketOpen = false; 82 | } 83 | } 84 | 85 | bool SerialIf_IsOpen() 86 | { 87 | if(m_Interface == IF_SERIAL) 88 | { 89 | return m_serialPort.isOpen(); 90 | } 91 | else if(m_Interface == IF_ETHERNET) 92 | { 93 | return m_SocketOpen; 94 | } 95 | 96 | return false; 97 | } 98 | 99 | void SerialIf_Clear() 100 | { 101 | m_serialPort.clear(); 102 | } 103 | 104 | bool SerialIf_SetDTR(bool state) 105 | { 106 | return m_serialPort.setDataTerminalReady(state); 107 | } 108 | 109 | QString SerialIf_GetError() 110 | { 111 | if(m_Interface == IF_SERIAL) 112 | { 113 | return m_serialPort.errorString(); 114 | } 115 | else if(m_Interface == IF_ETHERNET) 116 | { 117 | return m_tcpSocket.errorString(); 118 | } 119 | 120 | return QString(""); 121 | } 122 | 123 | qint64 SerialIf_Write(const QByteArray &data) 124 | { 125 | if(m_Interface == IF_SERIAL) 126 | { 127 | return m_serialPort.write(data); 128 | } 129 | else if(m_Interface == IF_ETHERNET) 130 | { 131 | /*if(m_tcpSocket.state() != QTcpSocket::ConnectedState) 132 | { 133 | qDebug() << "Disconnected. Trying to reopen"; 134 | m_tcpSocket.reset(); 135 | 136 | m_tcpSocket.connectToHost(m_ip, m_port); 137 | m_SocketOpen = m_tcpSocket.waitForConnected(3000); 138 | }*/ 139 | 140 | qint64 bytes = m_tcpSocket.write(data); 141 | if(bytes < 0) 142 | { 143 | qDebug() << "Error: " << m_tcpSocket.errorString(); 144 | } 145 | m_tcpSocket.waitForBytesWritten(4); 146 | 147 | return bytes; 148 | } 149 | qDebug() << "Unknown interface"; 150 | 151 | return 0; 152 | } 153 | 154 | qint64 SerialIf_Write(const char *data, qint64 len) 155 | { 156 | return SerialIf_Write(QByteArray(data, len)); 157 | } 158 | 159 | bool SerialIf_CanReadLine() 160 | { 161 | if(m_Interface == IF_SERIAL) 162 | { 163 | return m_serialPort.canReadLine(); 164 | } 165 | else if(m_Interface == IF_ETHERNET) 166 | { 167 | return m_tcpSocket.canReadLine(); 168 | } 169 | 170 | // No valid interface 171 | return false; 172 | } 173 | 174 | qint64 SerialIf_IsDataAvailable() 175 | { 176 | if(m_Interface == IF_SERIAL) 177 | { 178 | return m_serialPort.bytesAvailable(); 179 | } 180 | else if(m_Interface == IF_ETHERNET) 181 | { 182 | return m_tcpSocket.bytesAvailable(); 183 | } 184 | 185 | // No valid interface 186 | return 0; 187 | } 188 | 189 | QByteArray SerialIf_ReadLine() 190 | { 191 | if(m_Interface == IF_SERIAL) 192 | { 193 | return m_serialPort.readLine(); 194 | } 195 | else if(m_Interface == IF_ETHERNET) 196 | { 197 | return m_tcpSocket.readLine(); 198 | } 199 | 200 | // Return empty array 201 | return QByteArray(); 202 | } 203 | 204 | qint64 SerialIf_Read(quint8 *data, qint64 max) 205 | { 206 | if(m_Interface == IF_SERIAL) 207 | { 208 | return m_serialPort.read((char*)data, max); 209 | } 210 | else if(m_Interface == IF_ETHERNET) 211 | { 212 | return m_tcpSocket.read((char*)data, max); 213 | } 214 | 215 | // Return empty array 216 | return 0; 217 | } 218 | -------------------------------------------------------------------------------- /src/interface/SerialInterface.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALINTERFACE_H 2 | #define SERIALINTERFACE_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | typedef enum 13 | { 14 | IF_SERIAL = 0, IF_ETHERNET 15 | } Interface_e; 16 | 17 | 18 | void SerialIf_Init(); 19 | void SerialIf_DeInit(); 20 | 21 | bool SerialIf_OpenSerial(int protocol, QString portname, qint32 baud); 22 | bool SerialIf_OpenEth(QString ip, qint32 port); 23 | 24 | void SerialIf_Close(); 25 | bool SerialIf_IsOpen(); 26 | 27 | void SerialIf_Clear(); 28 | bool SerialIf_SetDTR(bool state); 29 | 30 | QString SerialIf_GetError(); 31 | 32 | qint64 SerialIf_Write(const QByteArray &data); 33 | qint64 SerialIf_Write(const char *data, qint64 len); 34 | 35 | bool SerialIf_CanReadLine(); 36 | qint64 SerialIf_IsDataAvailable(); 37 | 38 | QByteArray SerialIf_ReadLine(); 39 | qint64 SerialIf_Read(quint8 *data, qint64 max); 40 | 41 | 42 | /*class SerialInterface : public QObject 43 | { 44 | public: 45 | SerialInterface(); 46 | ~SerialInterface(); 47 | 48 | bool OpenSerial(int protocol, QString portname, qint32 baud); 49 | bool OpenEth(QString ip, qint32 port); 50 | 51 | virtual void Close(); 52 | virtual bool IsOpen(); 53 | 54 | virtual qint64 Write(const QByteArray &data); 55 | virtual qint64 Write(const char *data, qint64 len); 56 | 57 | virtual bool CanReadLine(); 58 | virtual QByteArray ReadLine(); 59 | 60 | private: 61 | QSerialPort m_serialPort; 62 | QTcpSocket m_tcpSocket; 63 | Interface_e m_Interface; 64 | int m_Protocol; 65 | bool m_SocketOpen; 66 | 67 | };*/ 68 | 69 | 70 | #endif // SERIALINTERFACE_H 71 | -------------------------------------------------------------------------------- /src/parser/arcproperties.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "ArcProperties.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #include "arcproperties.h" 9 | 10 | ArcProperties::ArcProperties() 11 | { 12 | radius = 0; 13 | center = NULL; 14 | } 15 | -------------------------------------------------------------------------------- /src/parser/arcproperties.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "ArcProperties.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef ARCPROPERTIES_H 9 | #define ARCPROPERTIES_H 10 | 11 | #include 12 | 13 | class ArcProperties 14 | { 15 | public: 16 | explicit ArcProperties(); 17 | bool isClockwise; 18 | double radius; 19 | QVector3D *center; 20 | }; 21 | 22 | #endif // ARCPROPERTIES_H 23 | -------------------------------------------------------------------------------- /src/parser/gcodeparser.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "GcodeParser.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef GCODEPARSER_H 9 | #define GCODEPARSER_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include "pointsegment.h" 15 | #include "gcodepreprocessorutils.h" 16 | 17 | class GcodeParser : public QObject 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit GcodeParser(QObject *parent = 0); 22 | ~GcodeParser(); 23 | 24 | bool getConvertArcsToLines(); 25 | void setConvertArcsToLines(bool convertArcsToLines); 26 | bool getRemoveAllWhitespace(); 27 | void setRemoveAllWhitespace(bool removeAllWhitespace); 28 | double getSmallArcSegmentLength(); 29 | void setSmallArcSegmentLength(double smallArcSegmentLength); 30 | double getSmallArcThreshold(); 31 | void setSmallArcThreshold(double smallArcThreshold); 32 | double getSpeedOverride(); 33 | void setSpeedOverride(double speedOverride); 34 | int getTruncateDecimalLength(); 35 | void setTruncateDecimalLength(int truncateDecimalLength); 36 | void reset(const QVector3D &initialPoint = QVector3D(qQNaN(), qQNaN(), qQNaN())); 37 | PointSegment *addCommand(QString command); 38 | PointSegment *addCommand(const QStringList &args); 39 | QVector3D* getCurrentPoint(); 40 | QList expandArc(); 41 | QStringList preprocessCommands(QStringList commands); 42 | QStringList preprocessCommand(QString command); 43 | QStringList convertArcsToLines(QString command); 44 | QList getPointSegmentList(); 45 | double getTraverseSpeed() const; 46 | void setTraverseSpeed(double traverseSpeed); 47 | int getCommandNumber() const; 48 | 49 | signals: 50 | 51 | public slots: 52 | 53 | private: 54 | 55 | // Current state 56 | bool m_isMetric; 57 | bool m_inAbsoluteMode; 58 | bool m_inAbsoluteIJKMode; 59 | float m_lastGcodeCommand; 60 | bool m_retractOldZ; 61 | QVector3D m_currentPoint; 62 | int m_commandNumber; 63 | PointSegment::planes m_currentPlane; 64 | double m_Angle; 65 | bool m_isRotationMove; 66 | 67 | // Settings 68 | double m_speedOverride; 69 | int m_truncateDecimalLength; 70 | bool m_removeAllWhitespace; 71 | bool m_convertArcsToLines; 72 | double m_smallArcThreshold; 73 | // Not configurable outside, but maybe it should be. 74 | double m_smallArcSegmentLength; 75 | 76 | double m_lastSpeed; 77 | double m_traverseSpeed; 78 | double m_lastSpindleSpeed; 79 | double m_lastDrillingDepth; 80 | 81 | // The gcode. 82 | QList m_points; 83 | 84 | PointSegment *processCommand(const QStringList &args); 85 | void handleMCode(float code, const QStringList &args); 86 | PointSegment *handleGCode(float code, const QStringList &args); 87 | PointSegment *addLinearPointSegment(const QVector3D &nextPoint, bool fastTraverse); 88 | PointSegment *addArcPointSegment(const QVector3D &nextPoint, bool clockwise, const QStringList &args); 89 | void setLastGcodeCommand(float num); 90 | }; 91 | 92 | #endif // GCODEPARSER_H 93 | -------------------------------------------------------------------------------- /src/parser/gcodepreprocessorutils.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "GcodePreprocessorUtils.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef GCODEPREPROCESSORUTILS_H 9 | #define GCODEPREPROCESSORUTILS_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include "pointsegment.h" 15 | 16 | class GcodePreprocessorUtils : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | static QString overrideSpeed(QString command, double speed, double *original = NULL); 21 | static QString removeComment(QString command); 22 | static QString parseComment(QString command); 23 | static QString truncateDecimals(int length, QString command); 24 | static QString removeAllWhitespace(QString command); 25 | static QList parseCodes(const QStringList &args, char code); 26 | static QList parseGCodes(QString command); 27 | static QList parseMCodes(QString command); 28 | static QStringList splitCommand(const QString &command); 29 | static double parseCoord(QStringList argList, char c); 30 | static QVector3D updatePointWithCommand(const QVector3D &initial, double x, double y, double z, bool absoluteMode); 31 | static QVector4D updatePointWithCommand(const QStringList &commandArgs, const QVector3D &initial, bool absoluteMode); 32 | static QVector3D updatePointWithCommand(const QString &command, const QVector3D &initial, bool absoluteMode); 33 | static QVector3D convertRToCenter(QVector3D start, QVector3D end, double radius, bool absoluteIJK, bool clockwise); 34 | static QVector3D updateCenterWithCommand(QStringList commandArgs, QVector3D initial, QVector3D nextPoint, bool absoluteIJKMode, bool clockwise); 35 | static QString generateG1FromPoints(QVector3D start, QVector3D end, bool absoluteMode, int precision); 36 | static double getAngle(QVector3D start, QVector3D end); 37 | static double calculateSweep(double startAngle, double endAngle, bool isCw); 38 | static QList generatePointsAlongArcBDring(PointSegment::planes plane, QVector3D start, QVector3D end, QVector3D center, bool clockwise, double R, double minArcLength, double arcPrecision, bool arcDegreeMode); 39 | static QList generatePointsAlongArcBDring(PointSegment::planes plane, QVector3D p1, QVector3D p2, QVector3D center, bool isCw, double radius, double startAngle, double sweep, int numPoints); 40 | static inline bool isDigit(char c); 41 | static inline bool isLetter(char c); 42 | static inline char toUpper(char c); 43 | 44 | static QVector3D rotateAxis(const QVector3D &init, double angle); 45 | signals: 46 | 47 | public slots: 48 | 49 | private: 50 | 51 | }; 52 | 53 | #endif // GCODEPREPROCESSORUTILS_H 54 | -------------------------------------------------------------------------------- /src/parser/gcodeviewparse.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "GcodeViewParse.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef GCODEVIEWPARSE_H 9 | #define GCODEVIEWPARSE_H 10 | 11 | #include 12 | #include 13 | #include 14 | #include "linesegment.h" 15 | #include "gcodeparser.h" 16 | #include "utils/util.h" 17 | 18 | class GcodeViewParse : public QObject 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit GcodeViewParse(QObject *parent = 0); 23 | ~GcodeViewParse(); 24 | 25 | QVector3D &getMinimumExtremes(); 26 | QVector3D &getMaximumExtremes(); 27 | double getMinLength() const; 28 | QSize getResolution() const; 29 | QList toObjRedux(QList gcode, double arcPrecision, bool arcDegreeMode); 30 | QList getLineSegmentList(); 31 | QList getLinesFromParser(GcodeParser *gp, double arcPrecision, bool arcDegreeMode); 32 | 33 | QList *getLines(); 34 | QVector> &getLinesIndexes(); 35 | 36 | void reset(); 37 | 38 | signals: 39 | 40 | public slots: 41 | 42 | private: 43 | bool absoluteMode; 44 | bool absoluteIJK; 45 | 46 | // Parsed object 47 | QVector3D m_min, m_max; 48 | double m_minLength; 49 | QList m_lines; 50 | QVector> m_lineIndexes; 51 | 52 | // Parsing state. 53 | QVector3D lastPoint; 54 | int currentLine; // for assigning line numbers to segments. 55 | 56 | // Debug 57 | bool debug; 58 | void testExtremes(QVector3D p3d); 59 | void testExtremes(double x, double y, double z); 60 | void testLength(const QVector3D &start, const QVector3D &end); 61 | }; 62 | 63 | #endif // GCODEVIEWPARSE_H 64 | -------------------------------------------------------------------------------- /src/parser/linesegment.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "LineSegment.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #include "linesegment.h" 9 | #include 10 | 11 | LineSegment::LineSegment() 12 | { 13 | m_toolhead = 0; //DEFAULT TOOLHEAD ASSUMED TO BE 0! 14 | m_isZMovement = false; 15 | m_isArc = false; 16 | m_isFastTraverse = false; 17 | m_drawn = false; 18 | m_isMetric = true; 19 | m_isAbsolute = true; 20 | m_isHightlight = false; 21 | m_vertexIndex = -1; 22 | } 23 | 24 | LineSegment::LineSegment(QVector3D a, QVector3D b, int num) : LineSegment() 25 | { 26 | // m_toolhead = 0; //DEFAULT TOOLHEAD ASSUMED TO BE 0! 27 | // m_isZMovement = false; 28 | // m_isArc = false; 29 | // m_isFastTraverse = false; 30 | 31 | m_first = a; 32 | m_second = b; 33 | m_lineNumber = num; 34 | } 35 | 36 | LineSegment::LineSegment(LineSegment* initial) 37 | { 38 | m_toolhead = initial->getToolhead(); 39 | m_isZMovement = initial->isZMovement(); 40 | m_isArc = initial->isArc(); 41 | m_isFastTraverse = initial->isFastTraverse(); 42 | m_drawn = initial->drawn(); 43 | m_first = initial->getStart(); 44 | m_second = initial->getEnd(); 45 | m_lineNumber = initial->getLineNumber(); 46 | m_speed = initial->getSpeed(); 47 | m_isMetric = initial->isMetric(); 48 | m_isAbsolute = initial->isAbsolute(); 49 | m_isHightlight = initial->isHightlight(); 50 | m_vertexIndex = initial->vertexIndex(); 51 | } 52 | 53 | LineSegment::~LineSegment() 54 | { 55 | 56 | } 57 | 58 | int LineSegment::getLineNumber() { 59 | return m_lineNumber; 60 | } 61 | 62 | QList LineSegment::getPointArray() 63 | { 64 | QList pointarr; 65 | pointarr.append(m_first); 66 | pointarr.append(m_second); 67 | return pointarr; 68 | } 69 | 70 | QList LineSegment::getPoints() 71 | { 72 | QList points; 73 | points.append(m_first.x()); 74 | points.append(m_first.y()); 75 | points.append(m_first.z()); 76 | points.append(m_second.x()); 77 | points.append(m_second.y()); 78 | points.append(m_second.z()); 79 | return points; 80 | } 81 | 82 | QVector3D &LineSegment::getStart() { 83 | return this->m_first; 84 | } 85 | 86 | void LineSegment::setStart(QVector3D vector) 87 | { 88 | m_first = vector; 89 | } 90 | 91 | QVector3D &LineSegment::getEnd() { 92 | return this->m_second; 93 | } 94 | 95 | void LineSegment::setEnd(QVector3D vector) 96 | { 97 | m_second = vector; 98 | } 99 | 100 | void LineSegment::setToolHead(int head) { 101 | this->m_toolhead = head; 102 | } 103 | 104 | int LineSegment::getToolhead() 105 | { 106 | return m_toolhead; 107 | } 108 | 109 | void LineSegment::setSpeed(double s) { 110 | this->m_speed = s; 111 | } 112 | 113 | double LineSegment::getSpeed() 114 | { 115 | return m_speed; 116 | } 117 | 118 | void LineSegment::setIsZMovement(bool isZ) { 119 | this->m_isZMovement = isZ; 120 | } 121 | 122 | bool LineSegment::isZMovement() { 123 | return m_isZMovement; 124 | } 125 | 126 | void LineSegment::setIsArc(bool isA) { 127 | this->m_isArc = isA; 128 | } 129 | 130 | bool LineSegment::isArc() { 131 | return m_isArc; 132 | } 133 | 134 | void LineSegment::setIsFastTraverse(bool isF) { 135 | this->m_isFastTraverse = isF; 136 | } 137 | 138 | bool LineSegment::isFastTraverse() { 139 | return this->m_isFastTraverse; 140 | } 141 | 142 | bool LineSegment::contains(const QVector3D &point) 143 | { 144 | double delta; 145 | QVector3D line = this->getEnd() - this->getStart(); 146 | QVector3D pt = point - this->getStart(); 147 | 148 | delta = (line - pt).length() - (line.length() - pt.length()); 149 | 150 | return delta < 0.01; 151 | } 152 | 153 | bool LineSegment::drawn() const 154 | { 155 | return m_drawn; 156 | } 157 | 158 | void LineSegment::setDrawn(bool drawn) 159 | { 160 | m_drawn = drawn; 161 | } 162 | bool LineSegment::isMetric() const 163 | { 164 | return m_isMetric; 165 | } 166 | 167 | void LineSegment::setIsMetric(bool isMetric) 168 | { 169 | m_isMetric = isMetric; 170 | } 171 | bool LineSegment::isAbsolute() const 172 | { 173 | return m_isAbsolute; 174 | } 175 | 176 | void LineSegment::setIsAbsolute(bool isAbsolute) 177 | { 178 | m_isAbsolute = isAbsolute; 179 | } 180 | bool LineSegment::isHightlight() const 181 | { 182 | return m_isHightlight; 183 | } 184 | 185 | void LineSegment::setIsHightlight(bool isHightlight) 186 | { 187 | m_isHightlight = isHightlight; 188 | } 189 | 190 | int LineSegment::vertexIndex() const 191 | { 192 | return m_vertexIndex; 193 | } 194 | 195 | void LineSegment::setVertexIndex(int vertexIndex) 196 | { 197 | m_vertexIndex = vertexIndex; 198 | } 199 | 200 | double LineSegment::getSpindleSpeed() const 201 | { 202 | return m_spindleSpeed; 203 | } 204 | 205 | void LineSegment::setSpindleSpeed(double spindleSpeed) 206 | { 207 | m_spindleSpeed = spindleSpeed; 208 | } 209 | 210 | double LineSegment::getDwell() const 211 | { 212 | return m_dwell; 213 | } 214 | 215 | void LineSegment::setDwell(double dwell) 216 | { 217 | m_dwell = dwell; 218 | } 219 | 220 | bool LineSegment::isClockwise() const 221 | { 222 | return m_isClockwise; 223 | } 224 | 225 | void LineSegment::setIsClockwise(bool isClockwise) 226 | { 227 | m_isClockwise = isClockwise; 228 | } 229 | 230 | PointSegment::planes LineSegment::plane() const 231 | { 232 | return m_plane; 233 | } 234 | 235 | void LineSegment::setPlane(const PointSegment::planes &plane) 236 | { 237 | m_plane = plane; 238 | } 239 | 240 | 241 | 242 | 243 | 244 | -------------------------------------------------------------------------------- /src/parser/linesegment.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "LineSegment.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef LINESEGMENT_H 9 | #define LINESEGMENT_H 10 | 11 | #include 12 | #include "pointsegment.h" 13 | 14 | class LineSegment 15 | { 16 | public: 17 | LineSegment(); 18 | LineSegment(QVector3D a, QVector3D b, int num); 19 | LineSegment(LineSegment *initial); 20 | ~LineSegment(); 21 | 22 | int getLineNumber(); 23 | QList getPointArray(); 24 | QList getPoints(); 25 | 26 | QVector3D &getStart(); 27 | void setStart(QVector3D vector); 28 | 29 | QVector3D &getEnd(); 30 | void setEnd(QVector3D vector); 31 | 32 | void setToolHead(int head); 33 | int getToolhead(); 34 | void setSpeed(double s); 35 | double getSpeed(); 36 | void setIsZMovement(bool isZ); 37 | bool isZMovement(); 38 | void setIsArc(bool isA); 39 | bool isArc(); 40 | void setIsFastTraverse(bool isF); 41 | bool isFastTraverse(); 42 | 43 | bool contains(const QVector3D &point); 44 | 45 | bool drawn() const; 46 | void setDrawn(bool drawn); 47 | 48 | bool isMetric() const; 49 | void setIsMetric(bool isMetric); 50 | 51 | bool isAbsolute() const; 52 | void setIsAbsolute(bool isAbsolute); 53 | 54 | bool isHightlight() const; 55 | void setIsHightlight(bool isHightlight); 56 | 57 | int vertexIndex() const; 58 | void setVertexIndex(int vertexIndex); 59 | 60 | double getSpindleSpeed() const; 61 | void setSpindleSpeed(double spindleSpeed); 62 | 63 | double getDwell() const; 64 | void setDwell(double dwell); 65 | 66 | bool isClockwise() const; 67 | void setIsClockwise(bool isClockwise); 68 | 69 | PointSegment::planes plane() const; 70 | void setPlane(const PointSegment::planes &plane); 71 | 72 | private: 73 | int m_toolhead; 74 | double m_speed; 75 | double m_spindleSpeed; 76 | double m_dwell; 77 | QVector3D m_first, m_second; 78 | 79 | // Line properties 80 | bool m_isZMovement; 81 | bool m_isArc; 82 | bool m_isClockwise; 83 | bool m_isFastTraverse; 84 | int m_lineNumber; 85 | bool m_drawn; 86 | bool m_isMetric; 87 | bool m_isAbsolute; 88 | bool m_isHightlight; 89 | int m_vertexIndex; 90 | 91 | PointSegment::planes m_plane; 92 | }; 93 | 94 | #endif // LINESEGMENT_H 95 | -------------------------------------------------------------------------------- /src/parser/pointsegment.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // This file was originally ported from "PointSegment.java" class 3 | // of "Universal GcodeSender" application written by Will Winder 4 | // (https://github.com/winder/Universal-G-Code-Sender) 5 | 6 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 7 | 8 | #ifndef POINTSEGMENT_H 9 | #define POINTSEGMENT_H 10 | 11 | #include 12 | 13 | #include "arcproperties.h" 14 | 15 | class PointSegment 16 | { 17 | public: 18 | enum planes { 19 | XY, 20 | ZX, 21 | YZ 22 | }; 23 | 24 | PointSegment(); 25 | PointSegment(PointSegment *ps); 26 | PointSegment(const QVector3D *b, int num); 27 | PointSegment(QVector3D *point, int num, QVector3D *center, double radius, bool clockwise); 28 | ~PointSegment(); 29 | void setPoint(QVector3D m_point); 30 | QVector3D* point(); 31 | 32 | QVector points(); 33 | void setToolHead(int head); 34 | int getToolhead(); 35 | void setLineNumber(int num); 36 | int getLineNumber(); 37 | void setSpeed(double s); 38 | double getSpeed(); 39 | void setIsZMovement(bool isZ); 40 | bool isZMovement(); 41 | void setIsMetric(bool m_isMetric); 42 | bool isMetric(); 43 | void setIsArc(bool isA); 44 | bool isArc(); 45 | void setIsFastTraverse(bool isF); 46 | bool isFastTraverse(); 47 | void setArcCenter(QVector3D *center); 48 | QVector centerPoints(); 49 | QVector3D *center(); 50 | void setIsClockwise(bool clockwise); 51 | bool isClockwise(); 52 | void setRadius(double rad); 53 | double getRadius(); 54 | void convertToMetric(); 55 | 56 | bool isAbsolute() const; 57 | void setIsAbsolute(bool isAbsolute); 58 | 59 | planes plane() const; 60 | void setPlane(const planes &plane); 61 | 62 | double getSpindleSpeed() const; 63 | void setSpindleSpeed(double spindleSpeed); 64 | 65 | double getDwell() const; 66 | void setDwell(double dwell); 67 | 68 | private: 69 | ArcProperties *m_arcProperties; 70 | int m_toolhead; 71 | double m_speed; 72 | double m_spindleSpeed; 73 | double m_dwell; 74 | QVector3D *m_point; 75 | bool m_isMetric; 76 | bool m_isZMovement; 77 | bool m_isArc; 78 | bool m_isFastTraverse; 79 | bool m_isAbsolute; 80 | int m_lineNumber; 81 | planes m_plane; 82 | }; 83 | 84 | #endif // POINTSEGMENT_H 85 | -------------------------------------------------------------------------------- /src/protocol/grbl1_1.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Schildkroet/Candle2/92654c50886b68e457c0024d2ebd39fee4fd3e73/src/protocol/grbl1_1.cpp -------------------------------------------------------------------------------- /src/protocol/grbl1_1.h: -------------------------------------------------------------------------------- 1 | #ifndef GRBL1_1_H_ 2 | #define GRBL1_1_H_ 3 | 4 | 5 | void GRBL1_1_Parse(); 6 | 7 | 8 | #endif // GRBL1_1_H_ 9 | -------------------------------------------------------------------------------- /src/shaders.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | shaders/fshader.glsl 4 | shaders/vshader.glsl 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/shaders/fshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | //Dash grid (px) = factor * pi; 8 | const float factor = 2.0; 9 | 10 | varying vec4 v_color; 11 | varying vec2 v_position; 12 | varying vec2 v_start; 13 | varying vec2 v_texture; 14 | 15 | uniform sampler2D texture; 16 | 17 | bool isNan(float val) 18 | { 19 | return (val > 65535.0); 20 | } 21 | 22 | void main() 23 | { 24 | // Draw dash lines 25 | if (!isNan(v_start.x)) { 26 | vec2 sub = v_position - v_start; 27 | float coord = length(sub.x) > length(sub.y) ? gl_FragCoord.x : gl_FragCoord.y; 28 | if (cos(coord / factor) > 0.0) discard; 29 | } 30 | 31 | // Set fragment color 32 | if (!isNan(v_texture.x)) { 33 | gl_FragColor = texture2D(texture, v_texture); 34 | } else { 35 | gl_FragColor = v_color; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/shaders/vshader.glsl: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | // Set default precision to medium 3 | precision mediump int; 4 | precision mediump float; 5 | #endif 6 | 7 | uniform mat4 mvp_matrix; 8 | uniform mat4 mv_matrix; 9 | 10 | attribute vec4 a_position; 11 | attribute vec4 a_color; 12 | attribute vec4 a_start; 13 | 14 | varying vec4 v_color; 15 | varying vec2 v_position; 16 | varying vec2 v_start; 17 | varying vec2 v_texture; 18 | 19 | bool isNan(float val) 20 | { 21 | return (val > 65535.0); 22 | } 23 | 24 | void main() 25 | { 26 | // Calculate interpolated vertex position & line start point 27 | v_position = (mv_matrix * a_position).xy; 28 | 29 | if (!isNan(a_start.x) && !isNan(a_start.y)) { 30 | v_start = (mv_matrix * a_start).xy; 31 | v_texture = vec2(65536.0, 0); 32 | } else { 33 | // v_start.x should be Nan to draw solid lines 34 | v_start = a_start.xy; 35 | 36 | // set texture coord 37 | v_texture = a_start.yz; 38 | 39 | // set point size 40 | if (isNan(a_start.y) && !isNan(a_start.z)) gl_PointSize = a_start.z; 41 | } 42 | 43 | // Calculate vertex position in screen space 44 | gl_Position = mvp_matrix * a_position; 45 | 46 | v_color = a_color; 47 | } 48 | -------------------------------------------------------------------------------- /src/tables/gcodetablemodel.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "gcodetablemodel.h" 5 | 6 | GCodeTableModel::GCodeTableModel(QObject *parent) : 7 | QAbstractTableModel(parent) 8 | { 9 | m_headers << tr("#") << tr("Command") << tr("State") << tr("Response") << tr("Line") << tr("Args"); 10 | } 11 | 12 | QVariant GCodeTableModel::data(const QModelIndex &index, int role) const 13 | { 14 | if (!index.isValid()) return QVariant(); 15 | 16 | if (index.row() >= m_data.size()) return QVariant(); 17 | 18 | if (role == Qt::DisplayRole || role == Qt::EditRole) { 19 | switch (index.column()) 20 | { 21 | case 0: return index.row() == this->rowCount() - 1 ? QString() : QString::number(index.row() + 1); 22 | case 1: return m_data.at(index.row()).command; 23 | case 2: 24 | if (index.row() == this->rowCount() - 1) return QString(); 25 | switch (m_data.at(index.row()).state) { 26 | case GCodeItem::InQueue: return tr("In queue"); 27 | case GCodeItem::Sent: return tr("Sent"); 28 | case GCodeItem::Processed: return tr("Processed"); 29 | case GCodeItem::Skipped: return tr("Skipped"); 30 | } 31 | return tr("Unknown"); 32 | case 3: return m_data.at(index.row()).response; 33 | case 4: return m_data.at(index.row()).line; 34 | case 5: return QVariant(m_data.at(index.row()).args); 35 | } 36 | } 37 | 38 | if (role == Qt::TextAlignmentRole) { 39 | switch (index.column()) { 40 | case 0: return Qt::AlignCenter; 41 | default: return Qt::AlignVCenter; 42 | } 43 | } 44 | 45 | return QVariant(); 46 | } 47 | 48 | bool GCodeTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 49 | { 50 | if (index.isValid() && role == Qt::EditRole) { 51 | switch (index.column()) 52 | { 53 | case 0: return false; 54 | case 1: m_data[index.row()].command = value.toString(); break; 55 | case 2: m_data[index.row()].state = value.toInt(); break; 56 | case 3: m_data[index.row()].response = value.toString(); break; 57 | case 4: m_data[index.row()].line = value.toInt(); break; 58 | case 5: m_data[index.row()].args = value.toStringList(); break; 59 | } 60 | emit dataChanged(index, index); 61 | return true; 62 | } 63 | return false; 64 | } 65 | 66 | bool GCodeTableModel::insertRow(int row, const QModelIndex &parent) 67 | { 68 | if (row > rowCount()) return false; 69 | 70 | beginInsertRows(parent, row, row); 71 | m_data.insert(row, GCodeItem()); 72 | endInsertRows(); 73 | return true; 74 | } 75 | 76 | bool GCodeTableModel::removeRow(int row, const QModelIndex &parent) 77 | { 78 | //if (!index(row, 0).isValid()) return false; 79 | 80 | beginRemoveRows(parent, row, row); 81 | m_data.removeAt(row); 82 | endRemoveRows(); 83 | return true; 84 | } 85 | 86 | bool GCodeTableModel::removeRows(int row, int count, const QModelIndex &parent) 87 | { 88 | beginRemoveRows(parent, row, row + count - 1); 89 | m_data.erase(m_data.begin() + row, m_data.begin() + row + count); 90 | endRemoveRows(); 91 | return true; 92 | } 93 | 94 | void GCodeTableModel::clear() 95 | { 96 | beginResetModel(); 97 | 98 | // foreach (GCodeItem* item, m_data) delete item; 99 | 100 | m_data.clear(); 101 | endResetModel(); 102 | } 103 | 104 | int GCodeTableModel::rowCount(const QModelIndex &parent) const 105 | { 106 | Q_UNUSED(parent) 107 | 108 | return m_data.size(); 109 | } 110 | 111 | int GCodeTableModel::columnCount(const QModelIndex &parent) const 112 | { 113 | Q_UNUSED(parent) 114 | 115 | return 6; 116 | } 117 | 118 | QVariant GCodeTableModel::headerData(int section, Qt::Orientation orientation, int role) const 119 | { 120 | if (role != Qt::DisplayRole) return QVariant(); 121 | if (orientation == Qt::Horizontal) return m_headers.at(section); 122 | else return QString::number(section + 1); 123 | } 124 | 125 | Qt::ItemFlags GCodeTableModel::flags(const QModelIndex &index) const 126 | { 127 | if (!index.isValid()) return NULL; 128 | if (index.column() == 1) return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; 129 | else return QAbstractTableModel::flags(index); 130 | } 131 | 132 | QList &GCodeTableModel::data() 133 | { 134 | return m_data; 135 | } 136 | -------------------------------------------------------------------------------- /src/tables/gcodetablemodel.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef GCODETABLEMODEL_H 5 | #define GCODETABLEMODEL_H 6 | 7 | #include 8 | #include 9 | 10 | struct GCodeItem 11 | { 12 | enum States { InQueue, Sent, Processed, Skipped }; 13 | 14 | QString command; 15 | char state; 16 | QString response; 17 | int line; 18 | QStringList args; 19 | }; 20 | 21 | class GCodeTableModel : public QAbstractTableModel 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit GCodeTableModel(QObject *parent = 0); 26 | 27 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 28 | bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); 29 | bool insertRow(int row, const QModelIndex &parent = QModelIndex()); 30 | bool removeRow(int row, const QModelIndex &parent = QModelIndex()); 31 | bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); 32 | void clear(); 33 | 34 | int rowCount(const QModelIndex &parent = QModelIndex()) const; 35 | int columnCount(const QModelIndex &parent = QModelIndex()) const; 36 | 37 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 38 | Qt::ItemFlags flags(const QModelIndex &index) const; 39 | 40 | QList &data(); 41 | 42 | signals: 43 | 44 | public slots: 45 | 46 | private: 47 | QList m_data; 48 | QStringList m_headers; 49 | }; 50 | 51 | #endif // GCODETABLEMODEL_H 52 | -------------------------------------------------------------------------------- /src/tables/heightmaptablemodel.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "heightmaptablemodel.h" 5 | 6 | HeightMapTableModel::HeightMapTableModel(QObject *parent) : QAbstractTableModel(parent) 7 | { 8 | m_data.append(QVector()); 9 | } 10 | 11 | void HeightMapTableModel::resize(int cols, int rows) 12 | { 13 | foreach (QVector row, m_data) row.clear(); 14 | 15 | m_data.clear(); 16 | 17 | for (int i = 0; i < rows; i++) { 18 | QVector row; 19 | for (int j = 0; j < cols; j++) { 20 | row.append(qQNaN()); 21 | } 22 | m_data.append(row); 23 | } 24 | } 25 | 26 | QVariant HeightMapTableModel::data(const QModelIndex &index, int role) const 27 | { 28 | if (!index.isValid()) return QVariant(); 29 | 30 | if (index.row() >= m_data.count() || index.column() >= m_data[0].count()) return QVariant(); 31 | 32 | if (role == Qt::DisplayRole || role == Qt::EditRole) { 33 | return QString::number(m_data[(m_data.count() - 1) - index.row()][index.column()], 'f', 3); 34 | } 35 | 36 | if (role == Qt::UserRole) { 37 | return m_data[index.row()][index.column()]; 38 | } 39 | 40 | if (role == Qt::TextAlignmentRole) { 41 | return Qt::AlignCenter; 42 | } 43 | 44 | return QVariant(); 45 | } 46 | 47 | bool HeightMapTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 48 | { 49 | m_data[role == Qt::EditRole ? (m_data.count() - 1) - index.row() : index.row()][index.column()] = value.toDouble(); 50 | 51 | if (role == Qt::EditRole) emit dataChangedByUserInput(); 52 | 53 | return true; 54 | } 55 | 56 | bool HeightMapTableModel::insertRow(int row, const QModelIndex &parent) 57 | { 58 | Q_UNUSED(parent) 59 | 60 | m_data.insert(row, QVector()); 61 | return true; 62 | } 63 | 64 | bool HeightMapTableModel::removeRow(int row, const QModelIndex &parent) 65 | { 66 | Q_UNUSED(parent) 67 | 68 | m_data.remove(row); 69 | return true; 70 | } 71 | 72 | void HeightMapTableModel::clear() 73 | { 74 | m_data.clear(); 75 | } 76 | 77 | int HeightMapTableModel::rowCount(const QModelIndex &parent) const 78 | { 79 | Q_UNUSED(parent) 80 | 81 | return m_data.count(); 82 | } 83 | 84 | int HeightMapTableModel::columnCount(const QModelIndex &parent) const 85 | { 86 | Q_UNUSED(parent) 87 | 88 | return m_data[0].count(); 89 | } 90 | 91 | QVariant HeightMapTableModel::headerData(int section, Qt::Orientation orientation, int role) const 92 | { 93 | Q_UNUSED(orientation) 94 | 95 | if (role != Qt::DisplayRole) return QVariant(); 96 | return QString::number(section + 1); 97 | } 98 | 99 | Qt::ItemFlags HeightMapTableModel::flags(const QModelIndex &index) const 100 | { 101 | if (!index.isValid()) return NULL; 102 | return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/tables/heightmaptablemodel.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef HEIGHTMAPTABLEMODEL_H 5 | #define HEIGHTMAPTABLEMODEL_H 6 | 7 | #include 8 | #include 9 | 10 | class HeightMapTableModel : public QAbstractTableModel 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit HeightMapTableModel(QObject *parent = 0); 15 | 16 | void resize(int cols, int rows); 17 | 18 | QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; 19 | bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); 20 | bool insertRow(int row, const QModelIndex &parent = QModelIndex()); 21 | bool removeRow(int row, const QModelIndex &parent = QModelIndex()); 22 | void clear(); 23 | 24 | int rowCount(const QModelIndex &parent = QModelIndex()) const; 25 | int columnCount(const QModelIndex &parent = QModelIndex()) const; 26 | 27 | QVariant headerData(int section, Qt::Orientation orientation, int role) const; 28 | Qt::ItemFlags flags(const QModelIndex &index) const; 29 | 30 | signals: 31 | void dataChangedByUserInput(); 32 | 33 | private: 34 | // QList> m_data; 35 | QVector> m_data; 36 | QList m_headers; 37 | }; 38 | 39 | #endif // HEIGHTMAPTABLEMODEL_H 40 | -------------------------------------------------------------------------------- /src/utils/interpolation.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef INTERPOLATION 5 | #define INTERPOLATION 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class Interpolation 13 | { 14 | public: 15 | static double cubicInterpolate(double p[4], double x) 16 | { 17 | return p[1] + 0.5 * x * (p[2] - p[0] + x *(2.0 * p[0] - 5.0 * p[1] 18 | + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0]))); 19 | } 20 | 21 | static double bicubicInterpolate(double p[4][4], double x, double y) 22 | { 23 | double arr[4]; 24 | arr[0] = cubicInterpolate(p[0], x); 25 | arr[1] = cubicInterpolate(p[1], x); 26 | arr[2] = cubicInterpolate(p[2], x); 27 | arr[3] = cubicInterpolate(p[3], x); 28 | return cubicInterpolate(arr, y); 29 | } 30 | 31 | static double bicubicInterpolate(QRectF borderRect, QAbstractTableModel *basePoints, double x, double y) 32 | { 33 | // Setup grid 34 | int gridPointsX = basePoints->columnCount(); 35 | int gridPointsY = basePoints->rowCount(); 36 | 37 | double gridStepX = gridPointsX > 1 ? borderRect.width() / (gridPointsX - 1) : 0; 38 | double gridStepY = gridPointsY > 1 ? borderRect.height() / (gridPointsY - 1) : 0; 39 | 40 | // Get 16 points 41 | x -= borderRect.x(); 42 | y -= borderRect.y(); 43 | 44 | int ix = trunc(x / gridStepX); 45 | int iy = trunc(y / gridStepY); 46 | 47 | if (ix > basePoints->columnCount() - 2) ix = basePoints->columnCount() - 2; 48 | if (iy > basePoints->rowCount() - 2) iy = basePoints->rowCount() - 2; 49 | 50 | double p[4][4]; 51 | 52 | p[0][0] = basePoints->data(basePoints->index((iy > 0 ? iy - 1 : iy), (ix > 0 ? ix - 1 : ix)), Qt::UserRole).toDouble(); 53 | p[0][1] = basePoints->data(basePoints->index((iy > 0 ? iy - 1 : iy), ix), Qt::UserRole).toDouble(); 54 | p[0][2] = basePoints->data(basePoints->index((iy > 0 ? iy - 1 : iy), ix + 1), Qt::UserRole).toDouble(); 55 | p[0][3] = basePoints->data(basePoints->index((iy > 0 ? iy - 1 : iy), (ix < basePoints->columnCount() - 2 ? ix + 2: ix + 1)), Qt::UserRole).toDouble(); 56 | 57 | p[1][0] = basePoints->data(basePoints->index(iy, ix > 0 ? ix - 1 : ix), Qt::UserRole).toDouble(); 58 | p[1][1] = basePoints->data(basePoints->index(iy, ix), Qt::UserRole).toDouble(); 59 | p[1][2] = basePoints->data(basePoints->index(iy, ix + 1), Qt::UserRole).toDouble(); 60 | p[1][3] = basePoints->data(basePoints->index(iy, ix < basePoints->columnCount() - 2 ? ix + 2: ix + 1), Qt::UserRole).toDouble(); 61 | 62 | p[2][0] = basePoints->data(basePoints->index(iy + 1, ix > 0 ? ix - 1 : ix), Qt::UserRole).toDouble(); 63 | p[2][1] = basePoints->data(basePoints->index(iy + 1, ix), Qt::UserRole).toDouble(); 64 | p[2][2] = basePoints->data(basePoints->index(iy + 1, ix + 1), Qt::UserRole).toDouble(); 65 | p[2][3] = basePoints->data(basePoints->index(iy + 1, ix < basePoints->columnCount() - 2 ? ix + 2 : ix + 1), Qt::UserRole).toDouble(); 66 | 67 | p[3][0] = basePoints->data(basePoints->index(iy < basePoints->rowCount() - 2 ? iy + 2 : iy + 1, ix > 0 ? ix - 1 : ix), Qt::UserRole).toDouble(); 68 | p[3][1] = basePoints->data(basePoints->index(iy < basePoints->rowCount() - 2 ? iy + 2 : iy + 1, ix), Qt::UserRole).toDouble(); 69 | p[3][2] = basePoints->data(basePoints->index(iy < basePoints->rowCount() - 2 ? iy + 2 : iy + 1, ix + 1), Qt::UserRole).toDouble(); 70 | p[3][3] = basePoints->data(basePoints->index(iy < basePoints->rowCount() - 2 ? iy + 2 : iy + 1, ix < basePoints->columnCount() - 2 ? ix + 2 : ix + 1), Qt::UserRole).toDouble(); 71 | 72 | // Interpolate 73 | return Interpolation::bicubicInterpolate(p, x / gridStepX - ix, y / gridStepY - iy); 74 | } 75 | }; 76 | 77 | #endif // INTERPOLATION 78 | 79 | -------------------------------------------------------------------------------- /src/utils/profiles.cpp: -------------------------------------------------------------------------------- 1 | #include "profiles.h" 2 | #include 3 | 4 | // chosen for backward compatibility with pre-profiles versions, which always stored settings in `settings.ini` 5 | const QString default_profile_name = "settings"; 6 | 7 | QStringList getProfileNames() 8 | { 9 | const QDir configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation); 10 | const QStringList configFiles = configDir.entryList({"*.ini"}, QDir::Files); 11 | QStringList rv; 12 | for (QString configFile : configFiles) 13 | { 14 | rv << QUrl::fromPercentEncoding(configFile.replace(QRegExp("\\.ini$"), "").toUtf8()); 15 | } 16 | return rv; 17 | } 18 | 19 | QString configPathForProfile(QString profile_name) 20 | { 21 | std::string configPath = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation).toStdString(); 22 | auto pos = configPath.rfind('/'); 23 | if (pos != std::string::npos) 24 | { 25 | configPath.erase(pos); 26 | } 27 | QString tmp = QString::fromStdString(configPath) + "/Candle2"; 28 | QDir configDir(tmp); 29 | return configDir.filePath(QUrl::toPercentEncoding(profile_name) + ".ini"); 30 | } 31 | -------------------------------------------------------------------------------- /src/utils/profiles.h: -------------------------------------------------------------------------------- 1 | #ifndef PROFILES_H 2 | #define PROFILES_H 3 | #include 4 | #include 5 | #include 6 | 7 | extern const QString default_profile_name; 8 | QStringList getProfileNames(); 9 | QString configPathForProfile(QString profile_name); 10 | 11 | #endif // PROFILES_H 12 | -------------------------------------------------------------------------------- /src/utils/safequeue.h: -------------------------------------------------------------------------------- 1 | #ifndef SAFEQUEUE_H 2 | #define SAFEQUEUE_H 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | template 12 | class SafeQueue 13 | { 14 | public: 15 | SafeQueue() {} 16 | 17 | void push_back(const T& val) 18 | { 19 | std::unique_lock lock(mMutex); 20 | mQueue.push_back(val); 21 | } 22 | 23 | void push_back(T&& val) 24 | { 25 | std::unique_lock lock(mMutex); 26 | mQueue.push_back(std::move(val)); 27 | } 28 | 29 | void push_front(const T& val) 30 | { 31 | std::unique_lock lock(mMutex); 32 | mQueue.push_front(val); 33 | } 34 | 35 | void push_front(T&& val) 36 | { 37 | std::unique_lock lock(mMutex); 38 | mQueue.push_front(std::move(val)); 39 | } 40 | 41 | T& front() 42 | { 43 | std::unique_lock lock(mMutex); 44 | return mQueue.front(); 45 | } 46 | 47 | T& back() 48 | { 49 | std::unique_lock lock(mMutex); 50 | return mQueue.back(); 51 | } 52 | 53 | void pop_front() 54 | { 55 | std::unique_lock lock(mMutex); 56 | if(!mQueue.empty()) 57 | { 58 | mQueue.pop_front(); 59 | } 60 | } 61 | 62 | typename std::list::iterator erase(typename std::list::const_iterator it) 63 | { 64 | std::unique_lock lock(mMutex); 65 | return mQueue.erase(it); 66 | } 67 | 68 | typename std::list::iterator get_at(int pos) 69 | { 70 | std::unique_lock lock(mMutex); 71 | 72 | auto it = mQueue.begin(); 73 | std::advance(it, pos); 74 | 75 | return it; 76 | } 77 | 78 | int size() 79 | { 80 | std::unique_lock lock(mMutex); 81 | return mQueue.size(); 82 | } 83 | 84 | bool empty() const 85 | { 86 | std::unique_lock lock(mMutex); 87 | return mQueue.empty(); 88 | } 89 | 90 | void clear() 91 | { 92 | mQueue.clear(); 93 | } 94 | 95 | private: 96 | std::list mQueue; 97 | mutable std::mutex mMutex; 98 | }; 99 | 100 | 101 | #endif // SAFEQUEUE_H 102 | -------------------------------------------------------------------------------- /src/utils/util.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef UTIL 5 | #define UTIL 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | class Util 16 | { 17 | public: 18 | static double nMin(double v1, double v2) 19 | { 20 | if (!qIsNaN(v1) && !qIsNaN(v2)) return qMin(v1, v2); 21 | else if (!qIsNaN(v1)) return v1; 22 | else if (!qIsNaN(v2)) return v2; 23 | else return qQNaN(); 24 | } 25 | 26 | static double nMax(double v1, double v2) 27 | { 28 | if (!qIsNaN(v1) && !qIsNaN(v2)) return qMax(v1, v2); 29 | else if (!qIsNaN(v1)) return v1; 30 | else if (!qIsNaN(v2)) return v2; 31 | else return qQNaN(); 32 | } 33 | 34 | static QVector3D colorToVector(QColor color) 35 | { 36 | return QVector3D(color.redF(), color.greenF(), color.blueF()); 37 | } 38 | 39 | static void waitEvents(int ms) 40 | { 41 | QEventLoop loop; 42 | 43 | QTimer::singleShot(ms, &loop, SLOT(quit())); 44 | loop.exec(); 45 | } 46 | 47 | static QIcon invertIconColors(QIcon icon) 48 | { 49 | QImage img = icon.pixmap(icon.actualSize(QSize(64, 64))).toImage(); 50 | img.invertPixels(); 51 | 52 | return QIcon(QPixmap::fromImage(img)); 53 | } 54 | 55 | static void invertButtonIconColors(QAbstractButton *button) 56 | { 57 | button->setIcon(invertIconColors(button->icon())); 58 | } 59 | }; 60 | 61 | #endif // UTIL 62 | 63 | -------------------------------------------------------------------------------- /src/widgets/colorpicker.cpp: -------------------------------------------------------------------------------- 1 | #include "colorpicker.h" 2 | 3 | ColorPicker::ColorPicker(QWidget *parent) : 4 | QWidget(parent) 5 | { 6 | m_layout = new QHBoxLayout(this); 7 | m_frame = new QFrame(this); 8 | m_button = new QToolButton(this); 9 | 10 | m_frame->setFrameShape(QFrame::Box); 11 | 12 | m_button->setText("..."); 13 | 14 | m_layout->setMargin(0); 15 | m_layout->addWidget(m_frame, 1); 16 | m_layout->addWidget(m_button); 17 | 18 | connect(m_button, SIGNAL(clicked()), this, SLOT(onButtonClicked())); 19 | } 20 | 21 | QColor ColorPicker::color() const 22 | { 23 | return m_color; 24 | } 25 | 26 | void ColorPicker::setColor(const QColor &color) 27 | { 28 | m_color = color; 29 | m_frame->setStyleSheet(QString("background-color: %1").arg(color.name())); 30 | } 31 | 32 | void ColorPicker::onButtonClicked() 33 | { 34 | QColor color = QColorDialog::getColor(m_color, this); 35 | 36 | if (color.isValid()) { 37 | setColor(color); 38 | emit colorSelected(color); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/widgets/colorpicker.h: -------------------------------------------------------------------------------- 1 | #ifndef COLORPICKER_H 2 | #define COLORPICKER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class ColorPicker : public QWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit ColorPicker(QWidget *parent = 0); 15 | 16 | QColor color() const; 17 | void setColor(const QColor &color); 18 | 19 | signals: 20 | void colorSelected(QColor color); 21 | 22 | public slots: 23 | 24 | private slots: 25 | void onButtonClicked(); 26 | 27 | private: 28 | QHBoxLayout *m_layout; 29 | QFrame *m_frame; 30 | QToolButton *m_button; 31 | QColor m_color; 32 | }; 33 | 34 | #endif // COLORPICKER_H 35 | -------------------------------------------------------------------------------- /src/widgets/combobox.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include 5 | #include 6 | #include "combobox.h" 7 | 8 | ComboBox::ComboBox(QWidget *parent) : QComboBox(parent) 9 | { 10 | } 11 | 12 | ComboBox::~ComboBox() 13 | { 14 | } 15 | 16 | void ComboBox::storeText() 17 | { 18 | if (this->count() == this->maxCount()) this->removeItem(this->maxCount() - 1); 19 | this->insertItem(0, this->currentText()); 20 | this->setCurrentIndex(-1); 21 | } 22 | 23 | void ComboBox::keyPressEvent(QKeyEvent *e) 24 | { 25 | if (e->key() == Qt::Key_Return) { 26 | if (this->count() == this->maxCount()) this->removeItem(this->maxCount() - 1); // TODO: Make removing selected item 27 | } 28 | QComboBox::keyPressEvent(e); 29 | 30 | if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { 31 | emit returnPressed(); 32 | this->setCurrentIndex(-1); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/widgets/combobox.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef COMBOBOX_H 5 | #define COMBOBOX_H 6 | 7 | #include 8 | #include 9 | 10 | class ComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit ComboBox(QWidget *parent = 0); 15 | ~ComboBox(); 16 | 17 | void storeText(); 18 | 19 | signals: 20 | void returnPressed(); 21 | 22 | protected: 23 | void keyPressEvent(QKeyEvent *e); 24 | }; 25 | 26 | #endif // COMBOBOX_H 27 | -------------------------------------------------------------------------------- /src/widgets/comboboxkey.cpp: -------------------------------------------------------------------------------- 1 | #include "comboboxkey.h" 2 | 3 | ComboBoxKey::ComboBoxKey(QWidget *parent) : QComboBox(parent) 4 | { 5 | } 6 | 7 | void ComboBoxKey::setEditable(bool editable) 8 | { 9 | if (!editable) { 10 | if (currentText() != itemText(currentIndex())) { 11 | // Remove user item if exist 12 | QString value = currentText(); 13 | if (itemData(count() - 1) == 1) { 14 | removeItem(count() - 1); 15 | removeItem(count() - 1); 16 | } 17 | 18 | // Add user item to the end of list 19 | insertSeparator(count()); 20 | addItem(value, 1); 21 | setCurrentIndex(count() - 1); 22 | } 23 | } 24 | 25 | QComboBox::setEditable(editable); 26 | } 27 | 28 | void ComboBoxKey::setCurrentNext() 29 | { 30 | do { 31 | setCurrentIndex(qMin(currentIndex() + 1, count() - 1)); 32 | } while (currentText().isEmpty()); 33 | } 34 | 35 | void ComboBoxKey::setCurrentPrevious() 36 | { 37 | do { 38 | setCurrentIndex(qMax(currentIndex() - 1, 0)); 39 | } while (currentText().isEmpty()); 40 | } 41 | 42 | void ComboBoxKey::setItems(QStringList items) 43 | { 44 | if (items.isEmpty()) return; 45 | 46 | clear(); 47 | 48 | bool userItem = false; 49 | foreach (QString item, items) { 50 | if (item.isEmpty()) { 51 | insertSeparator(count()); 52 | userItem = true; 53 | } else { 54 | insertItem(count(), item, userItem ? 1 : QVariant()); 55 | } 56 | } 57 | } 58 | 59 | QStringList ComboBoxKey::items() 60 | { 61 | QStringList items; 62 | 63 | for (int i = 0; i < count(); i++) items.append(itemText(i)); 64 | 65 | return items; 66 | } 67 | 68 | void ComboBoxKey::keyPressEvent(QKeyEvent *e) 69 | { 70 | if (this->isEditable() || !isBlockedKey(e->key())) QComboBox::keyPressEvent(e); 71 | } 72 | 73 | void ComboBoxKey::keyReleaseEvent(QKeyEvent *e) 74 | { 75 | if (this->isEditable() || !isBlockedKey(e->key())) QComboBox::keyReleaseEvent(e); 76 | } 77 | 78 | bool ComboBoxKey::isBlockedKey(int key) 79 | { 80 | return key != Qt::Key_ScrollLock && key != Qt::Key_Down && key != Qt::Key_Up; 81 | } 82 | -------------------------------------------------------------------------------- /src/widgets/comboboxkey.h: -------------------------------------------------------------------------------- 1 | #ifndef COMBOBOXKEY_H 2 | #define COMBOBOXKEY_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class ComboBoxKey : public QComboBox 10 | { 11 | public: 12 | explicit ComboBoxKey(QWidget *parent = 0); 13 | 14 | void setEditable(bool editable); 15 | 16 | void setCurrentNext(); 17 | void setCurrentPrevious(); 18 | 19 | void setItems(QStringList items); 20 | QStringList items(); 21 | 22 | protected: 23 | void keyPressEvent(QKeyEvent *e); 24 | void keyReleaseEvent(QKeyEvent *e); 25 | 26 | private: 27 | bool isBlockedKey(int key); 28 | }; 29 | 30 | #endif // COMBOBOXKEY_H 31 | -------------------------------------------------------------------------------- /src/widgets/glwidget.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef GLWIDGET_H 5 | #define GLWIDGET_H 6 | 7 | #ifndef GLES 8 | #include 9 | #else 10 | #include 11 | #endif 12 | 13 | #include 14 | #include 15 | #include "drawers/shaderdrawable.h" 16 | 17 | #ifdef GLES 18 | class GLWidget : public QOpenGLWidget 19 | #else 20 | class GLWidget : public QGLWidget, protected QOpenGLFunctions 21 | #endif 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit GLWidget(QWidget *parent = 0); 26 | ~GLWidget(); 27 | void addDrawable(ShaderDrawable *drawable); 28 | void updateExtremes(ShaderDrawable *drawable); 29 | void fitDrawable(ShaderDrawable *drawable = NULL); 30 | bool antialiasing() const; 31 | void setAntialiasing(bool antialiasing); 32 | 33 | QTime spendTime() const; 34 | void setSpendTime(const QTime &spendTime); 35 | 36 | QTime estimatedTime() const; 37 | void setEstimatedTime(const QTime &estimatedTime); 38 | 39 | double lineWidth() const; 40 | void setLineWidth(double lineWidth); 41 | 42 | void setIsometricView(); 43 | void setTopView(); 44 | void setFrontView(); 45 | void setLeftView(); 46 | 47 | int fps(); 48 | void setFps(int fps); 49 | 50 | QString parserStatus() const; 51 | void setParserStatus(const QString &parserStatus); 52 | 53 | QString bufferState() const; 54 | void setBufferState(const QString &bufferState); 55 | 56 | bool zBuffer() const; 57 | void setZBuffer(bool zBuffer); 58 | 59 | bool updatesEnabled() const; 60 | void setUpdatesEnabled(bool updatesEnabled); 61 | 62 | bool msaa() const; 63 | void setMsaa(bool msaa); 64 | 65 | QColor colorBackground() const; 66 | void setColorBackground(const QColor &colorBackground); 67 | 68 | QColor colorText() const; 69 | void setColorText(const QColor &colorText); 70 | 71 | double pointSize() const; 72 | void setPointSize(double pointSize); 73 | 74 | bool vsync() const; 75 | void setVsync(bool vsync); 76 | 77 | QString speedState() const; 78 | void setSpeedState(const QString &speedState); 79 | 80 | QString pinState() const; 81 | void setPinState(const QString &pinState); 82 | 83 | signals: 84 | void rotationChanged(); 85 | void resized(); 86 | 87 | public slots: 88 | 89 | private slots: 90 | void onFramesTimer(); 91 | void viewAnimation(); 92 | 93 | private: 94 | double m_xRot, m_yRot, m_xLastRot, m_yLastRot; 95 | double m_xPan, m_yPan, m_xLastPan, m_yLastPan; 96 | double m_xLookAt, m_yLookAt, m_zLookAt; 97 | QPoint m_lastPos; 98 | double m_zoom; 99 | double m_distance; 100 | double m_xMin, m_xMax, m_yMin, m_yMax, m_zMin, m_zMax, m_xSize, m_ySize, m_zSize; 101 | double m_lineWidth; 102 | double m_pointSize; 103 | bool m_antialiasing; 104 | bool m_msaa; 105 | bool m_vsync; 106 | bool m_zBuffer; 107 | int m_frames = 0; 108 | int m_fps = 0; 109 | int m_targetFps; 110 | int m_animationFrame; 111 | QTime m_spendTime; 112 | QTime m_estimatedTime; 113 | QBasicTimer m_timerPaint; 114 | double m_xRotTarget, m_yRotTarget; 115 | double m_xRotStored, m_yRotStored; 116 | bool m_animateView; 117 | QString m_parserStatus; 118 | QString m_speedState; 119 | QString m_pinState; 120 | QString m_bufferState; 121 | bool m_updatesEnabled; 122 | 123 | double normalizeAngle(double angle); 124 | double calculateVolume(QVector3D size); 125 | void beginViewAnimation(); 126 | void stopViewAnimation(); 127 | 128 | QList m_shaderDrawables; 129 | QOpenGLShaderProgram *m_shaderProgram; 130 | QMatrix4x4 m_projectionMatrix; 131 | QMatrix4x4 m_viewMatrix; 132 | 133 | QColor m_colorBackground; 134 | QColor m_colorText; 135 | 136 | protected: 137 | void initializeGL(); 138 | void resizeGL(int width, int height); 139 | void updateProjection(); 140 | void updateView(); 141 | #ifdef GLES 142 | void paintGL(); 143 | #else 144 | void paintEvent(QPaintEvent *pe); 145 | #endif 146 | 147 | void mousePressEvent(QMouseEvent *event); 148 | void mouseMoveEvent(QMouseEvent *event); 149 | void wheelEvent(QWheelEvent *we); 150 | 151 | void timerEvent(QTimerEvent *); 152 | }; 153 | 154 | #endif // GLWIDGET_H 155 | -------------------------------------------------------------------------------- /src/widgets/groupbox.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include 5 | #include 6 | #include 7 | #include "groupbox.h" 8 | 9 | GroupBox::GroupBox(QWidget *parent) : QGroupBox(parent) 10 | { 11 | 12 | } 13 | 14 | void GroupBox::mouseMoveEvent(QMouseEvent *event) 15 | { 16 | QGroupBox::mouseMoveEvent(event); 17 | 18 | if (!m_pressedPos.isNull()) { 19 | QPoint delta = event->globalPos() - m_pressedPos; 20 | emit mouseMoved(delta.x(), delta.y()); 21 | } 22 | } 23 | 24 | void GroupBox::mousePressEvent(QMouseEvent *event) 25 | { 26 | QGroupBox::mousePressEvent(event); 27 | 28 | m_pressedPos = event->globalPos(); 29 | emit mousePressed(); 30 | } 31 | 32 | void GroupBox::mouseReleaseEvent(QMouseEvent *event) 33 | { 34 | QGroupBox::mouseReleaseEvent(event); 35 | 36 | m_pressedPos = QPoint(); 37 | emit mouseReleased(); 38 | } 39 | 40 | void GroupBox::resizeEvent(QResizeEvent *event) 41 | { 42 | QGroupBox::resizeEvent(event); 43 | emit resized(event->size()); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/widgets/groupbox.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef GROUPBOX_H 5 | #define GROUPBOX_H 6 | 7 | #include 8 | #include 9 | 10 | class GroupBox : public QGroupBox 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit GroupBox(QWidget *parent = 0); 15 | 16 | signals: 17 | void mouseMoved(int dx, int dy); 18 | void mousePressed(); 19 | void mouseReleased(); 20 | void resized(QSize size); 21 | 22 | protected: 23 | void mouseMoveEvent(QMouseEvent *event); 24 | void mousePressEvent(QMouseEvent *event); 25 | void mouseReleaseEvent(QMouseEvent *event); 26 | void resizeEvent(QResizeEvent *event); 27 | 28 | private: 29 | QPoint m_pressedPos; 30 | }; 31 | 32 | #endif // GROUPBOX_H 33 | -------------------------------------------------------------------------------- /src/widgets/scrollarea.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "scrollarea.h" 11 | 12 | ScrollArea::ScrollArea(QWidget *parent) : QScrollArea(parent) 13 | { 14 | m_update = false; 15 | m_width = 0; 16 | 17 | this->setStyleSheet("QScrollArea {border-top: 2px solid transparent; border-bottom: 2px solid transparent;}\ 18 | QScrollArea[topBorder=\"true\"] {border-top: 2px solid qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:1 #D5DFE5, stop:0 white);}\ 19 | QScrollArea[bottomBorder=\"true\"] {border-bottom: 2px solid qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:1 #D5DFE5, stop:0 white);}"); 20 | 21 | this->verticalScrollBar()->setStyleSheet("QScrollBar:vertical {border: none; width: 2px; padding-top: 8px;}\ 22 | QScrollBar::handle:vertical {background: darkgray;}\ 23 | QScrollBar::add-line:vertical {border: none; background: none; height: 0px;}\ 24 | QScrollBar::sub-line:vertical {border: none; background: none; height: 0px;}"); 25 | 26 | connect(this->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onVerticalScrollBarValueChanged(int))); 27 | } 28 | 29 | QSize ScrollArea::sizeHint() const 30 | { 31 | QSize hint = widget()->sizeHint(); 32 | hint.setHeight(hint.height() + 4); // top + bottom border width 33 | hint.setWidth(m_width); 34 | 35 | return hint; 36 | } 37 | 38 | void ScrollArea::setWidget(QWidget *widget) 39 | { 40 | connect(static_cast(widget), SIGNAL(sizeChanged(QSize)), this, SLOT(onContentSizeChanged(QSize))); 41 | QScrollArea::setWidget(widget); 42 | } 43 | 44 | void ScrollArea::updateMinimumWidth() 45 | { 46 | m_width = 0; 47 | QList list = this->widget()->findChildren(); 48 | foreach (GroupBox *box, list) { 49 | connect(box, SIGNAL(mouseMoved(int,int)), this, SLOT(onScroll(int,int))); 50 | connect(box, SIGNAL(mousePressed()), this, SLOT(onPressed())); 51 | m_width = qMax(m_width, box->sizeHint().width() 52 | + static_cast(box->parent())->layout()->contentsMargins().left() 53 | + static_cast(box->parent())->layout()->contentsMargins().right()); // 1 * margin 54 | } 55 | onContentSizeChanged(QSize()); 56 | } 57 | 58 | void ScrollArea::resizeEvent(QResizeEvent *re) 59 | { 60 | QScrollArea::resizeEvent(re); 61 | 62 | updateBorders(); 63 | } 64 | 65 | void ScrollArea::mouseMoveEvent(QMouseEvent *me) 66 | { 67 | QScrollArea::mouseMoveEvent(me); 68 | 69 | if (!m_pressedPos.isNull()) { 70 | QPoint delta = me->globalPos() - m_pressedPos; 71 | onScroll(delta.x(), delta.y()); 72 | } 73 | } 74 | 75 | void ScrollArea::mousePressEvent(QMouseEvent *me) 76 | { 77 | QScrollArea::mousePressEvent(me); 78 | 79 | m_pressedPos = me->globalPos(); 80 | m_pressedValue = this->verticalScrollBar()->value(); 81 | } 82 | 83 | void ScrollArea::mouseReleaseEvent(QMouseEvent *me) 84 | { 85 | QScrollArea::mouseReleaseEvent(me); 86 | 87 | m_pressedPos = QPoint(); 88 | } 89 | 90 | void ScrollArea::onContentSizeChanged(QSize newSize) 91 | { 92 | Q_UNUSED(newSize) 93 | 94 | this->widget()->setMinimumWidth(m_width); 95 | this->updateGeometry(); 96 | } 97 | 98 | void ScrollArea::onVerticalScrollBarValueChanged(int newValue) 99 | { 100 | Q_UNUSED(newValue) 101 | 102 | updateBorders(); 103 | } 104 | 105 | void ScrollArea::onScroll(int dx, int dy) 106 | { 107 | Q_UNUSED(dx) 108 | 109 | QScrollBar *bar = this->verticalScrollBar(); 110 | int delta = (double)dy / (this->sizeHint().height() - this->height()) * (bar->maximum() - bar->minimum()); 111 | 112 | bar->setValue(m_pressedValue - delta); 113 | } 114 | 115 | void ScrollArea::onPressed() 116 | { 117 | m_pressedValue = this->verticalScrollBar()->value(); 118 | } 119 | 120 | void ScrollArea::updateBorders() 121 | { 122 | // Performance issue on changing stylesheet 123 | #ifdef GLES 124 | return; 125 | #else 126 | QScrollBar* bar = this->verticalScrollBar(); 127 | bool fitted = this->geometry().height() > this->widget()->sizeHint().height(); 128 | 129 | this->setProperty("topBorder", bar->value() > bar->minimum() && !fitted); 130 | this->setProperty("bottomBorder", bar->value() < bar->maximum() && !fitted); 131 | 132 | style()->unpolish(this); 133 | this->ensurePolished(); 134 | #endif 135 | } 136 | -------------------------------------------------------------------------------- /src/widgets/scrollarea.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef SCROLLAREA_H 5 | #define SCROLLAREA_H 6 | 7 | #include 8 | #include 9 | #include "widget.h" 10 | #include "groupbox.h" 11 | 12 | class ScrollArea : public QScrollArea 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit ScrollArea(QWidget *parent = 0); 18 | 19 | QSize sizeHint() const; 20 | void setWidget(QWidget *widget); 21 | void updateMinimumWidth(); 22 | 23 | public slots: 24 | 25 | signals: 26 | void sizeHintRequest(); 27 | 28 | protected: 29 | void resizeEvent(QResizeEvent *re); 30 | void mouseMoveEvent(QMouseEvent *me); 31 | void mousePressEvent(QMouseEvent *me); 32 | void mouseReleaseEvent(QMouseEvent *me); 33 | 34 | private slots: 35 | void onContentSizeChanged(QSize newSize); 36 | void onVerticalScrollBarValueChanged(int newValue); 37 | void onScroll(int dx, int dy); 38 | void onPressed(); 39 | 40 | private: 41 | bool m_update; 42 | QPoint m_pressedPos; 43 | int m_pressedValue; 44 | int m_width; 45 | 46 | void updateBorders(); 47 | }; 48 | 49 | #endif // SCROLLAREA_H 50 | -------------------------------------------------------------------------------- /src/widgets/slider.cpp: -------------------------------------------------------------------------------- 1 | #include "widgets/slider.h" 2 | 3 | Slider::Slider(QWidget *parent) : QSlider(parent) 4 | { 5 | m_currentValue = 250; 6 | } 7 | 8 | void Slider::paintEvent(QPaintEvent *ev) 9 | { 10 | QSlider::paintEvent(ev); 11 | 12 | if (this->currentValue() != this->value()) { 13 | 14 | QPainter painter(this); 15 | painter.setRenderHint(QPainter::Antialiasing); 16 | 17 | QImage image(":/images/handle2s1.png"); 18 | int pos = ((double)this->width() - 18) / (this->maximum() - this->minimum()) * (this->m_currentValue - this->minimum()) + 9; 19 | painter.drawImage(pos - image.width() / 2, (this->height() - image.height()) / 2, image); 20 | } 21 | } 22 | 23 | int Slider::currentValue() const 24 | { 25 | return m_currentValue; 26 | } 27 | 28 | void Slider::setCurrentValue(int currentValue) 29 | { 30 | if (m_currentValue != currentValue) { 31 | m_currentValue = currentValue; 32 | this->repaint(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/widgets/slider.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIDER_H 2 | #define SLIDER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Slider : public QSlider 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit Slider(QWidget *parent = 0); 15 | 16 | int currentValue() const; 17 | void setCurrentValue(int currentValue); 18 | 19 | protected: 20 | void paintEvent(QPaintEvent *ev); 21 | 22 | private: 23 | int m_currentValue; 24 | 25 | }; 26 | 27 | #endif // SLIDER_H 28 | -------------------------------------------------------------------------------- /src/widgets/sliderbox.cpp: -------------------------------------------------------------------------------- 1 | #include "sliderbox.h" 2 | #include "ui_sliderbox.h" 3 | 4 | SliderBox::SliderBox(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::SliderBox) 7 | { 8 | ui->setupUi(this); 9 | 10 | ui->chkTitle->setVisible(false); 11 | 12 | this->setCheckable(true); 13 | this->setRatio(1); 14 | this->setMinimum(0); 15 | this->setMaximum(10000); 16 | this->setValue(0); 17 | this->setCurrentValue(0); 18 | 19 | connect(&m_timerValueChanged, SIGNAL(timeout()), this, SLOT(onTimerValueChanged())); 20 | m_timerValueChanged.setInterval(250); 21 | } 22 | 23 | SliderBox::~SliderBox() 24 | { 25 | delete ui; 26 | } 27 | 28 | int SliderBox::value() 29 | { 30 | return ui->txtValue->value(); 31 | } 32 | 33 | void SliderBox::setValue(int value) 34 | { 35 | ui->txtValue->setValue(value); 36 | ui->sliValue->setValue(value / m_ratio); 37 | } 38 | 39 | int SliderBox::currentValue() 40 | { 41 | return m_currentValue; 42 | } 43 | 44 | void SliderBox::setCurrentValue(int value) 45 | { 46 | m_currentValue = value; 47 | 48 | ui->sliValue->setCurrentValue(value / m_ratio); 49 | ui->txtValue->setStyleSheet(value == ui->txtValue->value() || !this->isChecked() ? "color: palette(text);" : "color: red;"); 50 | } 51 | 52 | int SliderBox::sliderPosition() 53 | { 54 | return ui->sliValue->sliderPosition(); 55 | } 56 | 57 | void SliderBox::setSliderPosition(int position) 58 | { 59 | ui->sliValue->setSliderPosition(position); 60 | } 61 | 62 | bool SliderBox::isCheckable() const 63 | { 64 | return m_isCheckable; 65 | } 66 | 67 | void SliderBox::setCheckable(bool checkable) 68 | { 69 | m_isCheckable = checkable; 70 | 71 | ui->chkTitle->setVisible(checkable); 72 | ui->lblTitle->setVisible(!checkable); 73 | } 74 | 75 | bool SliderBox::isChecked() 76 | { 77 | return ui->chkTitle->isChecked(); 78 | } 79 | 80 | void SliderBox::setChecked(bool checked) 81 | { 82 | ui->chkTitle->setChecked(checked); 83 | } 84 | 85 | int SliderBox::ratio() const 86 | { 87 | return m_ratio; 88 | } 89 | 90 | void SliderBox::setRatio(int ratio) 91 | { 92 | m_ratio = ratio; 93 | } 94 | 95 | void SliderBox::on_txtValue_editingFinished() 96 | { 97 | ui->sliValue->setValue(ui->txtValue->value() / this->ratio()); 98 | emit valueUserChanged(); 99 | } 100 | 101 | void SliderBox::on_sliValue_actionTriggered(int action) 102 | { 103 | Q_UNUSED(action); 104 | 105 | ui->txtValue->setValue(ui->sliValue->sliderPosition() * this->ratio()); 106 | emit valueUserChanged(); 107 | } 108 | 109 | void SliderBox::on_sliValue_valueChanged(int value) 110 | { 111 | Q_UNUSED(value); 112 | 113 | if (this->isChecked()) { 114 | ui->txtValue->setStyleSheet("color: red;"); 115 | m_timerValueChanged.start(); 116 | } 117 | } 118 | 119 | void SliderBox::onTimerValueChanged() 120 | { 121 | m_timerValueChanged.stop(); 122 | emit valueChanged(); 123 | } 124 | 125 | int SliderBox::maximum() const 126 | { 127 | return m_maximum; 128 | } 129 | 130 | void SliderBox::setMaximum(int maximum) 131 | { 132 | m_maximum = maximum; 133 | 134 | ui->txtValue->setMaximum(maximum); 135 | ui->sliValue->setMaximum(maximum / m_ratio); 136 | } 137 | 138 | QString SliderBox::suffix() 139 | { 140 | return ui->txtValue->suffix(); 141 | } 142 | 143 | void SliderBox::setSuffix(QString suffix) 144 | { 145 | ui->txtValue->setSuffix(suffix); 146 | } 147 | 148 | QString SliderBox::title() 149 | { 150 | return ui->chkTitle->text(); 151 | } 152 | 153 | void SliderBox::setTitle(QString title) 154 | { 155 | ui->chkTitle->setText(title); 156 | ui->lblTitle->setText(title); 157 | } 158 | 159 | int SliderBox::minimum() const 160 | { 161 | return m_minimum; 162 | } 163 | 164 | void SliderBox::setMinimum(int minimum) 165 | { 166 | m_minimum = minimum; 167 | 168 | ui->txtValue->setMinimum(minimum); 169 | ui->sliValue->setMinimum(minimum / m_ratio); 170 | } 171 | 172 | void SliderBox::on_chkTitle_toggled(bool checked) 173 | { 174 | emit toggled(checked); 175 | } 176 | -------------------------------------------------------------------------------- /src/widgets/sliderbox.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIDERBOX_H 2 | #define SLIDERBOX_H 3 | 4 | #include 5 | #include 6 | 7 | namespace Ui { 8 | class SliderBox; 9 | } 10 | 11 | class SliderBox : public QWidget 12 | { 13 | Q_OBJECT 14 | public: 15 | explicit SliderBox(QWidget *parent = 0); 16 | ~SliderBox(); 17 | 18 | int value(); 19 | void setValue(int value); 20 | 21 | int currentValue(); 22 | void setCurrentValue(int value); 23 | 24 | int sliderPosition(); 25 | void setSliderPosition(int position); 26 | 27 | bool isCheckable() const; 28 | void setCheckable(bool checkable); 29 | 30 | bool isChecked(); 31 | void setChecked(bool checked); 32 | 33 | int ratio() const; 34 | void setRatio(int ratio); 35 | 36 | int minimum() const; 37 | void setMinimum(int minimum); 38 | 39 | int maximum() const; 40 | void setMaximum(int maximum); 41 | 42 | QString suffix(); 43 | void setSuffix(QString suffix); 44 | 45 | QString title(); 46 | void setTitle(QString title); 47 | 48 | signals: 49 | void valueUserChanged(); 50 | void valueChanged(); 51 | void toggled(bool checked); 52 | 53 | private slots: 54 | void onTimerValueChanged(); 55 | 56 | void on_txtValue_editingFinished(); 57 | 58 | void on_sliValue_actionTriggered(int action); 59 | 60 | void on_sliValue_valueChanged(int value); 61 | 62 | void on_chkTitle_toggled(bool checked); 63 | 64 | private: 65 | Ui::SliderBox *ui; 66 | 67 | bool m_isCheckable; 68 | int m_ratio; 69 | 70 | int m_currentValue; 71 | int m_minimum, m_maximum; 72 | 73 | QTimer m_timerValueChanged; 74 | }; 75 | 76 | #endif // SLIDERBOX_H 77 | -------------------------------------------------------------------------------- /src/widgets/sliderbox.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | SliderBox 4 | 5 | 6 | 7 | 0 8 | 0 9 | 185 10 | 50 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 0 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | 32 | 33 | 34 | Title: 35 | 36 | 37 | 38 | 39 | 40 | 41 | Title: 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 0 50 | 0 51 | 52 | 53 | 54 | Qt::AlignCenter 55 | 56 | 57 | QAbstractSpinBox::NoButtons 58 | 59 | 60 | 10 61 | 62 | 63 | 200 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 10 73 | 74 | 75 | 200 76 | 77 | 78 | Qt::Horizontal 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Slider 87 | QSlider 88 |
widgets/slider.h
89 |
90 |
91 | 92 | 93 |
94 | -------------------------------------------------------------------------------- /src/widgets/styledtoolbutton.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include "styledtoolbutton.h" 5 | #include 6 | #include 7 | 8 | StyledToolButton::StyledToolButton(QWidget *parent) : QToolButton(parent) 9 | { 10 | m_hovered = false; 11 | m_backColor = palette().color(QPalette::Button); 12 | m_foreColor = palette().color(QPalette::ButtonText); 13 | m_highlightColor = QColor(127, 211, 255).darker(120); 14 | } 15 | 16 | bool StyledToolButton::isHover() 17 | { 18 | return m_hovered; 19 | } 20 | 21 | void StyledToolButton::enterEvent(QEvent *e) 22 | { 23 | Q_UNUSED(e) 24 | 25 | m_hovered = true; 26 | } 27 | 28 | void StyledToolButton::leaveEvent(QEvent *e) 29 | { 30 | Q_UNUSED(e) 31 | 32 | m_hovered = false; 33 | } 34 | 35 | void StyledToolButton::paintEvent(QPaintEvent *e) 36 | { 37 | Q_UNUSED(e) 38 | 39 | const int borderWidth = 4; 40 | const int borderRadius = 5; 41 | 42 | QPainter painter(this); 43 | 44 | painter.setRenderHint(QPainter::Antialiasing); 45 | painter.setRenderHint(QPainter::HighQualityAntialiasing); 46 | 47 | // Highlight 48 | QPen highlightPen; 49 | 50 | if ((!this->isEnabled() && !this->isChecked()) || (!this->isDown() && !this->isChecked() && !this->isHover())) { 51 | highlightPen.setColor(Qt::white); 52 | } else if (this->isDown() || this->isChecked()) { 53 | highlightPen.setColor(m_highlightColor); 54 | } else if (this->isHover()) { 55 | highlightPen.setColor(m_highlightColor.lighter(120)); 56 | } 57 | 58 | highlightPen.setWidth(2); 59 | painter.setPen(highlightPen); 60 | painter.drawRoundedRect(1, 1, this->width() - 2, this->height() - 2, borderRadius - 1, borderRadius - 1); 61 | 62 | // Border 63 | QPen pen(this->isEnabled() ? palette().color(QPalette::Shadow) : palette().color(QPalette::Mid)); 64 | 65 | if ((this->isDown() || this->isChecked()) && this->isEnabled()) pen.setColor(Qt::black); 66 | 67 | pen.setWidth(2); 68 | pen.setCapStyle(Qt::SquareCap); 69 | painter.setPen(pen); 70 | 71 | painter.drawLine(borderRadius, 0, width() - borderRadius, 0); 72 | painter.drawLine(borderRadius, height(), width() - borderRadius, height()); 73 | painter.drawLine(0, borderRadius, 0, height() - borderRadius); 74 | painter.drawLine(width(), borderRadius, width(), height() - borderRadius); 75 | 76 | pen.setWidth(1); 77 | painter.setPen(pen); 78 | painter.drawArc(0, 0, borderRadius * 2, borderRadius * 2, 90 * 16, 90 * 16); 79 | painter.drawArc(width() - borderRadius * 2, 0, borderRadius * 2, borderRadius * 2, 0 * 16, 90 * 16); 80 | painter.drawArc(0, height() - borderRadius * 2, borderRadius * 2, borderRadius * 2, 180 * 16, 90 * 16); 81 | painter.drawArc(width() - borderRadius * 2, height() - borderRadius * 2, borderRadius * 2, borderRadius * 2, 270 * 16, 90 * 16); 82 | 83 | // Background border 84 | QLinearGradient backGradient(width() / 2, height() / 2, width() / 2, height()); 85 | backGradient.setColorAt(0, this->isEnabled() ? m_backColor : palette().color(QPalette::Button)); 86 | backGradient.setColorAt(1, this->isEnabled() ? m_backColor.darker(130) : palette().color(QPalette::Button).darker(130)); 87 | QBrush backBrush(backGradient); 88 | painter.setBrush(backBrush); 89 | painter.setPen(Qt::NoPen); 90 | painter.drawRoundedRect(borderWidth - 1, borderWidth - 1, width() - borderWidth * 2 + 2, height() - borderWidth * 2 + 2, 2, 2); 91 | 92 | // Background 93 | painter.setBrush(this->isEnabled() ? m_backColor : palette().color(QPalette::Button)); 94 | painter.setPen(Qt::NoPen); 95 | painter.drawRect(borderWidth, borderWidth, width() - borderWidth * 2, height() - borderWidth * 2); 96 | 97 | // Icon/text rect 98 | QRect innerRect(borderWidth, borderWidth, width() - borderWidth * 2, height() - borderWidth * 2); 99 | if (this->isDown() || this->isChecked()) { 100 | innerRect.setLeft(innerRect.left() + 2); 101 | innerRect.setTop(innerRect.top() + 2); 102 | } 103 | 104 | // Icon 105 | if (!this->icon().isNull()) { 106 | QSize iconSize = this->icon().actualSize(this->iconSize()); 107 | painter.drawPixmap(QRect(innerRect.x() + (innerRect.width() - iconSize.width()) / 2, 108 | innerRect.y() + (innerRect.height() - iconSize.height()) / 2, 109 | iconSize.width(), iconSize.height()), 110 | this->icon().pixmap(iconSize, this->isEnabled() ? QIcon::Normal : QIcon::Disabled)); 111 | } else { 112 | // Text 113 | painter.setPen(this->isEnabled() ? m_foreColor : palette().color(QPalette::Mid)); 114 | painter.drawText(innerRect, Qt::AlignCenter, this->text()); 115 | } 116 | } 117 | QColor StyledToolButton::highlightColor() const 118 | { 119 | return m_highlightColor; 120 | } 121 | 122 | void StyledToolButton::setHighlightColor(const QColor &highlightColor) 123 | { 124 | m_highlightColor = highlightColor; 125 | } 126 | 127 | QColor StyledToolButton::foreColor() const 128 | { 129 | return m_foreColor; 130 | } 131 | 132 | void StyledToolButton::setForeColor(const QColor &foreColor) 133 | { 134 | m_foreColor = foreColor; 135 | } 136 | 137 | QColor StyledToolButton::backColor() const 138 | { 139 | return m_backColor; 140 | } 141 | 142 | void StyledToolButton::setBackColor(const QColor &backColor) 143 | { 144 | m_backColor = backColor; 145 | } 146 | 147 | 148 | -------------------------------------------------------------------------------- /src/widgets/styledtoolbutton.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef STYLEDTOOLBUTTON_H 5 | #define STYLEDTOOLBUTTON_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | class StyledToolButton : public QToolButton 14 | { 15 | public: 16 | explicit StyledToolButton(QWidget *parent = 0); 17 | 18 | bool isHover(); 19 | 20 | QColor backColor() const; 21 | void setBackColor(const QColor &backColor); 22 | 23 | QColor foreColor() const; 24 | void setForeColor(const QColor &foreColor); 25 | 26 | QColor highlightColor() const; 27 | void setHighlightColor(const QColor &highlightColor); 28 | 29 | protected: 30 | void enterEvent(QEvent *); 31 | void leaveEvent(QEvent *); 32 | 33 | private: 34 | void paintEvent(QPaintEvent *e); 35 | 36 | bool m_hovered; 37 | QColor m_backColor; 38 | QColor m_foreColor; 39 | QColor m_highlightColor; 40 | }; 41 | 42 | #endif // STYLEDTOOLBUTTON_H 43 | -------------------------------------------------------------------------------- /src/widgets/widget.cpp: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #include 5 | #include 6 | #include "widget.h" 7 | 8 | Widget::Widget(QWidget *parent) : QWidget(parent) 9 | { 10 | 11 | } 12 | 13 | void Widget::resizeEvent(QResizeEvent *re) 14 | { 15 | emit sizeChanged(re->size()); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/widgets/widget.h: -------------------------------------------------------------------------------- 1 | // This file is a part of "Candle" application. 2 | // Copyright 2015-2016 Hayrullin Denis Ravilevich 3 | 4 | #ifndef WIDGET_H 5 | #define WIDGET_H 6 | 7 | #include 8 | 9 | class Widget : public QWidget 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit Widget(QWidget *parent = 0); 14 | 15 | signals: 16 | void sizeChanged(QSize newSize); 17 | 18 | protected: 19 | void resizeEvent(QResizeEvent *); 20 | 21 | public slots: 22 | }; 23 | 24 | #endif // WIDGET_H 25 | --------------------------------------------------------------------------------