├── .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 | 
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
116 |
--------------------------------------------------------------------------------
/src/images/search_z.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------