mirror of
https://github.com/Keychron/qmk_firmware.git
synced 2024-12-28 12:09:16 +06:00
515 lines
17 KiB
C
515 lines
17 KiB
C
/* Copyright 2021 Batuhan Başerdem
|
|
* <baserdem.batuhan@gmail.com> @bbaserdem
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#include "bb-encoder.h"
|
|
|
|
// Need this to call velocikey activation
|
|
#ifdef VELOCIKEY_ENABLE
|
|
# include "velocikey.h"
|
|
#endif // VELOCIKEY_ENABLE
|
|
// Need memcpy and memcmp from string.h along with transfer stuff
|
|
#ifdef OLED_ENABLE
|
|
# include <string.h>
|
|
#endif // OLED_ENABLE
|
|
|
|
/* ROTARY ENCODER
|
|
* This contains my general rotary encoder code
|
|
* Encoders each have a list of different modes they can be in.
|
|
* Each mode also have an on click action as well.
|
|
* Modes can be cycled using either shift-click or ctrl-click
|
|
* Modes can be reset using OS click
|
|
* Some modes are only accessible through some keymap layers
|
|
*/
|
|
|
|
// Default state for the encoders
|
|
void reset_encoder_state(void) {
|
|
userspace_config.e0base = 0;
|
|
userspace_config.e0point = 0;
|
|
userspace_config.e0rgb = 0;
|
|
userspace_config.e1base = 1;
|
|
userspace_config.e1point = 1;
|
|
userspace_config.e1rgb = 1;
|
|
}
|
|
|
|
// Encoder scroll functionality
|
|
bool encoder_update_user(uint8_t index, bool clockwise) {
|
|
uint8_t this_number;
|
|
// Differentiate layer roles
|
|
switch (get_highest_layer(layer_state)) {
|
|
# ifdef RGB_MATRIX_ENABLE
|
|
case _MEDI:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0rgb;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1rgb;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Effect the RGB mode
|
|
if (clockwise) {
|
|
rgb_matrix_step_noeeprom();
|
|
} else {
|
|
rgb_matrix_step_reverse_noeeprom();
|
|
}
|
|
break;
|
|
case 1: // Effect the RGB hue
|
|
if (clockwise) {
|
|
rgb_matrix_increase_hue_noeeprom();
|
|
} else {
|
|
rgb_matrix_decrease_hue_noeeprom();
|
|
}
|
|
break;
|
|
case 2: // Effect the RGB saturation
|
|
if (clockwise) {
|
|
rgb_matrix_increase_sat_noeeprom();
|
|
} else {
|
|
rgb_matrix_decrease_sat_noeeprom();
|
|
}
|
|
break;
|
|
case 3: // Effect the RGB brightness
|
|
if (clockwise) {
|
|
rgb_matrix_increase_val_noeeprom();
|
|
} else {
|
|
rgb_matrix_decrease_val_noeeprom();
|
|
}
|
|
break;
|
|
case 4: // Effect the RGB effect speed
|
|
if (clockwise) {
|
|
rgb_matrix_increase_speed_noeeprom();
|
|
} else {
|
|
rgb_matrix_decrease_speed_noeeprom();
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
# endif // RGB_MATRIX_ENABLE
|
|
# ifdef MOUSEKEY_ENABLE
|
|
case _MOUS:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0point;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1point;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Move mouse on horizontal axis
|
|
if (clockwise) {
|
|
tap_code(KC_MS_R);
|
|
} else {
|
|
tap_code(KC_MS_L);
|
|
}
|
|
break;
|
|
case 1: // Move mouse on vertical axis
|
|
if (clockwise) {
|
|
tap_code(KC_MS_D);
|
|
} else {
|
|
tap_code(KC_MS_U);
|
|
}
|
|
break;
|
|
case 2: // Move mouse wheel on vertical axis
|
|
if (clockwise) {
|
|
tap_code(KC_WH_D);
|
|
} else {
|
|
tap_code(KC_WH_U);
|
|
}
|
|
break;
|
|
case 3: // Move mouse on horizontal axis
|
|
if (clockwise) {
|
|
tap_code(KC_WH_R);
|
|
} else {
|
|
tap_code(KC_WH_L);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
# endif // MOUSEKEY_ENABLE
|
|
default:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0base;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1base;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Volume
|
|
if (clockwise) {
|
|
tap_code16(KC_VOLU);
|
|
} else {
|
|
tap_code16(KC_VOLD);
|
|
}
|
|
break;
|
|
case 1: // Song change
|
|
if (clockwise) {
|
|
tap_code16(KC_MNXT);
|
|
} else {
|
|
tap_code16(KC_MPRV);
|
|
}
|
|
break;
|
|
case 2: // Move to audio sink
|
|
if (clockwise) {
|
|
tap_code16(KC_F13);
|
|
} else {
|
|
tap_code16(S(KC_F13));
|
|
}
|
|
break;
|
|
case 3: // Volume of source
|
|
if (clockwise) {
|
|
tap_code16(S(KC_VOLU));
|
|
} else {
|
|
tap_code16(C(KC_VOLD));
|
|
}
|
|
break;
|
|
case 4: // Move to audio source
|
|
if (clockwise) {
|
|
tap_code16(C(KC_F13));
|
|
} else {
|
|
tap_code16(C(S(KC_F13)));
|
|
}
|
|
break;
|
|
case 5: // Left-right
|
|
if (clockwise) {
|
|
tap_code16(KC_RGHT);
|
|
} else {
|
|
tap_code16(KC_LEFT);
|
|
}
|
|
break;
|
|
case 6: // Up-down
|
|
if (clockwise) {
|
|
tap_code16(KC_DOWN);
|
|
} else {
|
|
tap_code16(KC_UP);
|
|
}
|
|
break;
|
|
case 7: // Page Up-down
|
|
if (clockwise) {
|
|
tap_code16(KC_PGDN);
|
|
} else {
|
|
tap_code16(KC_PGUP);
|
|
}
|
|
break;
|
|
case 8: // Delete
|
|
if (clockwise) {
|
|
tap_code16(KC_DEL);
|
|
} else {
|
|
tap_code16(KC_BSPC);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void encoder_click_action(uint8_t index) {
|
|
uint8_t this_number;
|
|
// Differentiate layer roles
|
|
switch (get_highest_layer(layer_state)) {
|
|
# ifdef RGB_MATRIX_ENABLE
|
|
case _MEDI:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0rgb;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1rgb;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Return to no animation
|
|
rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR);
|
|
break;
|
|
case 1:
|
|
case 2:
|
|
case 3: // Toggle
|
|
rgb_matrix_increase_val_noeeprom();
|
|
break;
|
|
case 4: // Toggle velocikey
|
|
# ifdef VELOCIKEY_ENABLE
|
|
velocikey_toggle();
|
|
# endif // VELOCIKEY_ENABLE
|
|
break;
|
|
}
|
|
break;
|
|
# endif // RGB_MATRIX_ENABLE
|
|
# ifdef MOUSEKEY_ENABLE
|
|
case _MOUS:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0point;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1point;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Left click
|
|
tap_code16(KC_BTN1);
|
|
break;
|
|
case 1: // Right click
|
|
tap_code16(KC_BTN2);
|
|
break;
|
|
case 2:
|
|
case 3: // Middle click
|
|
tap_code16(KC_BTN2);
|
|
break;
|
|
}
|
|
break;
|
|
# endif // MOUSEKEY_ENABLE
|
|
default:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0base;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1base;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch(this_number) {
|
|
case 0: // Toggle mute
|
|
case 2:
|
|
tap_code16(KC_MUTE);
|
|
break;
|
|
case 1: // Pause
|
|
tap_code16(KC_MPLY);
|
|
break;
|
|
case 3: // Mute source
|
|
case 4:
|
|
tap_code16(A(KC_MUTE));
|
|
break;
|
|
case 5: // Insert
|
|
tap_code16(KC_INS);
|
|
break;
|
|
case 6: // Capslock
|
|
tap_code16(KC_CAPS);
|
|
break;
|
|
case 7: // Redo
|
|
tap_code16(BB_REDO);
|
|
break;
|
|
case 8: // Undo
|
|
tap_code16(BB_UNDO);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool process_record_encoder(uint16_t keycode, keyrecord_t *record) {
|
|
// Check if and which encoder
|
|
int encoder_index = -1;
|
|
|
|
// Get the pressed encoder
|
|
switch (keycode) {
|
|
case BB_ENC0:
|
|
encoder_index = 0;
|
|
break;
|
|
case BB_ENC1:
|
|
encoder_index = 1;
|
|
break;
|
|
}
|
|
|
|
// Activate encoder function of button
|
|
if ((encoder_index >= 0) & (!record->event.pressed)) {
|
|
// If shifted, move mode one point forward
|
|
if (get_mods() & MOD_MASK_SHIFT) {
|
|
switch (get_highest_layer(layer_state)) {
|
|
# ifdef RGB_MATRIX_ENABLE
|
|
case _MEDI:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0rgb = (userspace_config.e0rgb + 1) % 5;
|
|
} else {
|
|
userspace_config.e1rgb = (userspace_config.e1rgb + 1) % 5;
|
|
}
|
|
break;
|
|
# endif // RGB_MATRIX_ENABLE
|
|
# ifdef MOUSEKEY_ENABLE
|
|
case _MOUS:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0point = (userspace_config.e0point + 1) % 4;
|
|
} else {
|
|
userspace_config.e1point = (userspace_config.e1point + 1) % 4;
|
|
}
|
|
break;
|
|
# endif // MOUSEKEY_ENABLE
|
|
default:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0base = (userspace_config.e0base + 1) % 9;
|
|
} else {
|
|
userspace_config.e1base = (userspace_config.e1base + 1) % 9;
|
|
}
|
|
break;
|
|
}
|
|
// If ctrl is active, move mode one point backwards
|
|
} else if (get_mods() & MOD_MASK_CTRL) {
|
|
switch (get_highest_layer(layer_state)) {
|
|
# ifdef RGB_MATRIX_ENABLE
|
|
case _MEDI:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0rgb = (userspace_config.e0rgb + 5 - 1) % 5;
|
|
} else {
|
|
userspace_config.e1rgb = (userspace_config.e1rgb + 5 - 1) % 5;
|
|
}
|
|
break;
|
|
# endif // RGB_MATRIX_ENABLE
|
|
# ifdef MOUSEKEY_ENABLE
|
|
case _MOUS:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0point = (userspace_config.e0point + 4 - 1) % 4;
|
|
} else {
|
|
userspace_config.e1point = (userspace_config.e1point + 4 - 1) % 4;
|
|
}
|
|
break;
|
|
# endif // MOUSEKEY_ENABLE
|
|
default:
|
|
if (encoder_index == 0) {
|
|
userspace_config.e0base = (userspace_config.e0base + 9 - 1) % 9;
|
|
} else {
|
|
userspace_config.e1base = (userspace_config.e1base + 9 - 1) % 9;
|
|
}
|
|
break;
|
|
}
|
|
// If meta is active, reset the encoder states
|
|
} else if (get_mods() & MOD_MASK_GUI) {
|
|
reset_encoder_state();
|
|
eeconfig_update_user(userspace_config.raw);
|
|
// If nothing else; just perform the click action
|
|
} else {
|
|
encoder_click_action(encoder_index);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// For printing status to OLED
|
|
#ifdef OLED_ENABLE
|
|
void encoder_state_string(uint8_t index, uint8_t layer, char* buffer) {
|
|
uint8_t this_number;
|
|
// Get the layer straight from the main function
|
|
switch (layer) {
|
|
// If RGB control mode is enabled
|
|
# ifdef RGB_MATRIX_ENABLE
|
|
case _MEDI:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0rgb;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1rgb;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch (this_number) {
|
|
case 0:
|
|
strcpy(buffer, "ani mode");
|
|
break;
|
|
case 1:
|
|
strcpy(buffer, "hue ");
|
|
break;
|
|
case 2:
|
|
strcpy(buffer, "saturat.");
|
|
break;
|
|
case 3:
|
|
strcpy(buffer, "bright. ");
|
|
break;
|
|
case 4:
|
|
strcpy(buffer, "ani. spd");
|
|
break;
|
|
default:
|
|
strcpy(buffer, " -N/A- ");
|
|
break;
|
|
}
|
|
break;
|
|
# endif // RGB_MATRIX_ENABLE
|
|
// If pointer control is enabled
|
|
# ifdef MOUSEKEY_ENABLE
|
|
case _MOUS:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0point;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1point;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch (this_number) {
|
|
case 0:
|
|
strcpy(buffer, "Lateral ");
|
|
break;
|
|
case 1:
|
|
strcpy(buffer, "Vertical");
|
|
break;
|
|
case 2:
|
|
strcpy(buffer, "Scr. Ver");
|
|
break;
|
|
case 3:
|
|
strcpy(buffer, "Scr. Lat");
|
|
break;
|
|
default:
|
|
strcpy(buffer, " -N/A- ");
|
|
break;
|
|
}
|
|
break;
|
|
# endif // MOUSEKEY_ENABLE
|
|
default:
|
|
// Get correct index
|
|
if (index == 0) {
|
|
this_number = userspace_config.e0base;
|
|
} else if (index == 1) {
|
|
this_number = userspace_config.e1base;
|
|
} else {
|
|
this_number = 128;
|
|
}
|
|
switch (this_number) {
|
|
case 0:
|
|
strcpy(buffer, "Volume ");
|
|
break;
|
|
case 1:
|
|
strcpy(buffer, "Song ");
|
|
break;
|
|
case 2:
|
|
strcpy(buffer, "Sink ");
|
|
break;
|
|
case 3:
|
|
strcpy(buffer, "Src. Vol");
|
|
break;
|
|
case 4:
|
|
strcpy(buffer, "Source ");
|
|
break;
|
|
case 5:
|
|
strcpy(buffer, "Arrow LR");
|
|
break;
|
|
case 6:
|
|
strcpy(buffer, "Arrow UD");
|
|
break;
|
|
case 7:
|
|
strcpy(buffer, "Page U/D");
|
|
break;
|
|
case 8:
|
|
strcpy(buffer, "Erase ");
|
|
break;
|
|
default:
|
|
strcpy(buffer, " -N/A- ");
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#endif // OLED_ENABLE
|