~ruther/qmk_firmware

857716794b233f3d4ac078c85a5a142091264aa6 — Mikael Manukyan 4 years ago 8db1d22
gmmk/pro/mike1808 keymap (#13398)

* Add gmmk/pro/mike1808 keymap

* Add licenses

* Update readme

* Add underglow support for rgb matrix layers

* Change FN to TT

* Fix rgb layer disabling during rgb settings change

* also clean up some code
A keyboards/gmmk/pro/keymaps/mike1808/.gitignore => keyboards/gmmk/pro/keymaps/mike1808/.gitignore +1 -0
@@ 0,0 1,1 @@
secrets.h

A keyboards/gmmk/pro/keymaps/mike1808/README.md => keyboards/gmmk/pro/keymaps/mike1808/README.md +19 -0
@@ 0,0 1,19 @@
QMK layout for gmmk/pro
=======================

## Secrets
The format is the same as [drashna's](../../../../users/drashna/readme_secrets.md) secrets implementation. Create a `secret.h` and define your secrets like this:

```c
static const char* secrets[] = {"secret1", "secret2", "secret3", "secret4", "secret5"};
```

## Rotary encoder knob
You can hookup your encoder functions by defining new encoder states in [encoder.h](./encoder.h), then in [encoder.c](./encoder.c) assign static variable `state` your new state depending on your desired condition and add callbacks to `encoder_mapping` array. 

## RGB Matrix Ledmaps
RGB Matrix ledmaps is the future allowing you assign colors to individual keys on every keymap layer. 

You can see some examples of my usage in the bottom of [keymap.c](./keymap.c).

Color defines are just HSV colors wrapped in curly braces, like `#define RED { HSV_RED }`.

A keyboards/gmmk/pro/keymaps/mike1808/config.h => keyboards/gmmk/pro/keymaps/mike1808/config.h +31 -0
@@ 0,0 1,31 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */

#define COMBO_COUNT 1
#define COMBO_TERM 100

#define RGB_MATRIX_KEYPRESSES
#define RGB_DISABLE_WHEN_USB_SUSPENDED true
#define RGB_DISABLE_TIMEOUT 90000

#define MACRO_TIMER 5

#define TAPPING_TOGGLE 3

#define WPM_SMOOTHING 0.1

// this is for macOS so keyboard can work after sleep
#define NO_USB_STARTUP_CHECK

A keyboards/gmmk/pro/keymaps/mike1808/encoder.c => keyboards/gmmk/pro/keymaps/mike1808/encoder.c +111 -0
@@ 0,0 1,111 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "encoder.h"
#include "mike1808.h"
#include "print.h"
#include "utils.h"
#include "process_record.h"
#include "rgb_matrix_ledmaps.h"

static uint8_t state = ENCODER_DEFAULT;

// clang-format off
const encoder_callback encoder_mapping[][2] = {
    [ENCODER_VOLUME] = {&volume_up, &volume_down},
#ifdef RGB_MATRIX_ENABLE
    [ENCODER_RGB_HUE] = {&rgb_matrix_increase_hue_noeeprom, &rgb_matrix_decrease_hue_noeeprom},
    [ENCODER_RGB_SAT] = {&rgb_matrix_increase_sat_noeeprom, &rgb_matrix_decrease_sat_noeeprom},
    [ENCODER_RGB_VAL] = {&rgb_matrix_increase_val_noeeprom, &rgb_matrix_decrease_val_noeeprom},
    [ENCODER_RGB_EFFECT] = {&rgb_matrix_step_noeeprom, &rgb_matrix_step_reverse_noeeprom},
    [ENCODER_RGB_EFFECT_SPEED] = {&rgb_matrix_increase_speed_noeeprom, &rgb_matrix_decrease_speed_noeeprom},
#endif // RGB_MATRIX_ENABLE
};

// clang-format on

void volume_up() { tap_code(KC_VOLU); }

void volume_down() { tap_code(KC_VOLD); }

bool encoder_update_user(uint8_t index, bool clockwise) {
    dprintf("current encoder state is: %d\n", state);

    if (clockwise) {
        (*encoder_mapping[state][0])();
    } else {
        (*encoder_mapping[state][1])();
    }

    return true;
}

void handle_rgb_key(bool pressed) {
    dprintf("handle_rgb_key %d\f", pressed);

    if (pressed) {
        rgb_matrix_layers_disable();
    } else {
        rgb_matrix_layers_enable();
    }
}

static KeyPressState *rgb_state;

void keyboard_post_init_encoder() {
    rgb_state = NewKeyPressState(handle_rgb_key);
}

bool process_record_encoder(uint16_t keycode, keyrecord_t *record) {
#ifdef RGB_MATRIX_ENABLE
    switch (keycode) {
        case KC_RGB_ENC_HUE ... KC_RGB_ENC_EFFECT:
            if (record->event.pressed) {
#    ifdef RGB_MATRIX_LEDMAPS_ENABLED
                // disable layers so we can adjust RGB effects
                rgb_state->press(rgb_state);
#    endif  // RGB_MATRIX_LEDMAPS_ENABLED

                switch (keycode) {
                    case KC_RGB_ENC_HUE:
                        state = ENCODER_RGB_HUE;
                        break;
                    case KC_RGB_ENC_SAT:
                        state = ENCODER_RGB_SAT;
                        break;
                    case KC_RGB_ENC_VAL:
                        state = ENCODER_RGB_VAL;
                        break;
                    case KC_RGB_ENC_EFFECT_SPEED:
                        state = ENCODER_RGB_EFFECT_SPEED;
                        break;
                    case KC_RGB_ENC_EFFECT:
                        state = ENCODER_RGB_EFFECT;
                        break;
                }
            } else {
#    ifdef RGB_MATRIX_LEDMAPS_ENABLED
                rgb_state->release(rgb_state);
#    endif  // RGB_MATRIX_LEDMAPS_ENABLED
                state = ENCODER_DEFAULT;
                store_rgb_state_to_eeprom();
            }

            return false;
    }
#endif  // RGB_MATRIX_ENABLE

    return true;
}

A keyboards/gmmk/pro/keymaps/mike1808/encoder.h => keyboards/gmmk/pro/keymaps/mike1808/encoder.h +35 -0
@@ 0,0 1,35 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */

// To add a new functionality define a new state here and then assign
// the handler to the `encoder_callback`
#include "quantum.h"

enum encoder_state {
    ENCODER_VOLUME = 0,
    ENCODER_RGB_HUE,
    ENCODER_RGB_SAT,
    ENCODER_RGB_VAL,
    ENCODER_RGB_EFFECT_SPEED,
    ENCODER_RGB_EFFECT,
};

typedef void (*encoder_callback)(void);

#define ENCODER_DEFAULT ENCODER_VOLUME

void volume_up(void);
void volume_down(void);

A keyboards/gmmk/pro/keymaps/mike1808/fun.c => keyboards/gmmk/pro/keymaps/mike1808/fun.c +49 -0
@@ 0,0 1,49 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "mike1808.h"
#include "print.h"

static bool wpm_rgb_enabled = false;
static uint8_t rgb_mode;

void rgb_matrix_indicators_keymap(void) {
    if (wpm_rgb_enabled && rgb_matrix_is_enabled()) {
        uint8_t wpm = get_current_wpm();
        dprintf("WPM = %d\n", wpm);
        HSV hsv = rgb_matrix_get_hsv();
        hsv.h = wpm;
        RGB rgb = hsv_to_rgb(hsv);
        rgb_matrix_set_color_all(rgb.r, rgb.g, rgb.b);
    }
}

bool process_record_fun(uint16_t keycode, keyrecord_t *record) {
    if (record->event.pressed && keycode == KC_WPM_RGB) {
        if (wpm_rgb_enabled) {
            wpm_rgb_enabled = false;
            rgb_matrix_mode(rgb_mode);
        } else {
            wpm_rgb_enabled = true;
            rgb_mode = rgb_matrix_get_mode();
            rgb_matrix_enable();
            rgb_matrix_mode(RGB_MATRIX_SOLID_COLOR);
        }

        return false;
    }

    return true;
}

A keyboards/gmmk/pro/keymaps/mike1808/keymap.c => keyboards/gmmk/pro/keymaps/mike1808/keymap.c +127 -0
@@ 0,0 1,127 @@
/* Copyright 2021 Glorious, LLC <salman@pcgamingrace.com>, Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "mike1808.h"

const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END};

combo_t key_combos[COMBO_COUNT] = {
    [JK_ESC] = COMBO(jk_combo, KC_ESC),
};

// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {

//      ESC      F1       F2       F3       F4       F5       F6       F7       F8       F9       F10      F11      F12	     Prt           Rotary(Mute)
//      ~        1        2        3        4        5        6        7        8        9        0         -       (=)	     BackSpc           Del
//      Tab      Q        W        E        R        T        Y        U        I        O        P        [        ]        \                 PgUp
//      Caps     A        S        D        F        G        H        J        K        L        ;        "                 Enter             PgDn
//      Sh_L              Z        X        C        V        B        N        M        ,        .        ?                 Sh_R     Up       End
//      Ct_L     Win_L    Alt_L                               SPACE                               Alt_R    FN       Ct_R     Left     Down     Right
    [LINUX] = LAYOUT(
        KC_ESC,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_DEL,           KC_MUTE,
        KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,  KC_BSPC,          KC_HOME,
        KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC, KC_BSLS,          KC_PGUP,
        KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,          KC_ENT,           KC_PGDN,
        KC_LSFT,          KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH,          KC_RSFT, KC_UP,   KC_END,
        KC_LCTL, KC_LGUI, KC_LALT,                            KC_SPC,                             KC_RALT,   TT_FN, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT
    ),

    [WINDOWS] = LAYOUT(
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,          _______,
        _______,          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______,
        _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______
    ),

    [MACOS] = LAYOUT(
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,          _______,
        _______,          _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______,
        _______, KC_LALT, KC_LGUI,                            _______,                            _______, _______, _______, _______, _______, _______
    ),

    [FUNCTIONS] = LAYOUT(
        _______, KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5, _______, _______, _______, _______, KC_MPRV, KC_MPLY, KC_MNXT, KC_PSCR,          _______,
        _______, KC_LINX, KC_MAC,  KC_WIN,  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,            KC_INS,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,  KC_RST,          _______,
        KC_CAPS, _______, _______, _______, _______,  OS_GIT, _______, _______, _______, _______, _______, _______,          _______,          _______,
        _______,          KC_RGBH, KC_RGBS, KC_RGBV, KC_RGBE, KC_RGBP, KC_WRGB, _______, _______, _______, _______,          _______, KC_PGUP, _______,
        _______, _______, _______,                            RGB_TOG,                            _______, _______, _______, KC_HOME, KC_PGDN, KC_END
    ),

    [GIT] = LAYOUT(
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,
        _______, _______, _______,  G_DIFF, _______, _______, _______, _______, _______, _______,  G_PULL,   G_PUSH, _______, _______,          _______,
        _______,   G_ADD, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______,          _______,
        _______,          _______, _______, G_CHECK, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______,
        _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______
    ),
};

#ifdef RGB_MATRIX_LEDMAPS_ENABLED

#define ______ {0, 0, 0}

const ledmap PROGMEM ledmaps[] = {
         //  LU = Left Underglow, RU = Right Underglow
         //  LU_1    ESC      F1       F2       F3       F4       F5       F6       F7       F8       F9       F10      F11      F12	     Prt           Rotary(Mute)  RU_1
         //  LU_2    ~        1        2        3        4        5        6        7        8        9        0         -       (=)	     BackSpc           Del       RU_2
         //  LU_3    Tab      Q        W        E        R        T        Y        U        I        O        P        [        ]        \                 PgUp         RU_3
         //  LU_4    Caps     A        S        D        F        G        H        J        K        L        ;        "                 Enter             PgDn         RU_4
         //  LU_5    Sh_L              Z        X        C        V        B        N        M        ,        .        ?                 Sh_R     Up       End          RU_5
         //  LU_6    Ct_L     Win_L    Alt_L                               SPACE                               Alt_R    FN       Ct_R     Left     Down     Right        RU_6
    [LINUX] = RGB_MATRIX_LAYOUT_LEDMAP(
          PURPLE,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          PURPLE,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          PURPLE,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          PURPLE,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,         ______,    PURPLE,
          PURPLE,    ______,         ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______, ______, ______,    PURPLE,
          PURPLE,    ______,    RED, ______,                         ______,                         ______, ______, ______, ______, ______, ______,    PURPLE
    ),
    [WINDOWS] = RGB_MATRIX_LAYOUT_LEDMAP(
          GREEN,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          GREEN,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          GREEN,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          GREEN,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,         ______,    PURPLE,
          GREEN,    ______,         ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______, ______, ______,    PURPLE,
          GREEN,    ______,    RED, ______,                         ______,                         ______, ______, ______, ______, ______, ______,    PURPLE
    ),
    [MACOS] = RGB_MATRIX_LAYOUT_LEDMAP(
          YELLOW,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          YELLOW,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          YELLOW,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,    PURPLE,
          YELLOW,    ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______,         ______,    PURPLE,
          YELLOW,    ______,         ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,         ______, ______, ______,    PURPLE,
          YELLOW,    ______, ______,    RED,                         ______,                         ______, ______, ______, ______, ______, ______,    PURPLE
    ),

    [FUNCTIONS] = RGB_MATRIX_LAYOUT_LEDMAP(
          CYAN,    GREEN,  GREEN,  GREEN,  GREEN,  GREEN,  GREEN, ______, ______, ______, ______,  GREEN,  GREEN,  GREEN,  GREEN,         ______,    PURPLE,
          CYAN,   ______,   GOLD,   GOLD,   GOLD, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,           GOLD,    PURPLE,
          CYAN,   ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______, ______,   TEAL,         ______,    PURPLE,
          CYAN,     TURQ, ______, ______, ______, ______,   TURQ, ______, ______, ______, ______, ______, ______,         ______,         ______,    PURPLE,
          CYAN,   ______,            RED,    RED,    RED,    RED,    RED,    RED, ______, ______, ______, ______,         ______,    RED, ______,    PURPLE,
          CYAN,   ______, ______,   BLUE,                         ______,                         ______, ______, ______, ______, ______, ______,    PURPLE
    ),
};

#endif // RGB_MATRIX_LEDMAPS_ENABLED
// clang-format on

A keyboards/gmmk/pro/keymaps/mike1808/mike1808.c => keyboards/gmmk/pro/keymaps/mike1808/mike1808.c +68 -0
@@ 0,0 1,68 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "mike1808.h"

#if (__has_include("secrets.h") && !defined(NO_SECRETS))
#    include "secrets.h"
#else
// `PROGMEM const char secret[][x]` may work better, but it takes up more space in the firmware
// And I'm not familiar enough to know which is better or why...
static const char *const secret[] = {"test1", "test2", "test3", "test4", "test5"};
#endif

// userspace_config_t userspace_config;

bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
    switch (keycode) {
        case KC_SECRET_1 ... KC_SECRET_5:  // Secrets!  Externally defined strings, not stored in repo
            if (!record->event.pressed) {
                clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
                send_string_with_delay(secrets[keycode - KC_SECRET_1], MACRO_TIMER);
            }
            return false;
            break;
    }
    return true;
}

void suspend_power_down_user(void) {
#ifdef RGB_MATRIX_ENABLE
    rgb_matrix_set_suspend_state(true);
#endif  // RGB_MATRIX_ENABLE
}

void suspend_wakeup_init_user(void) {
#ifdef RGB_MATRIX_ENABLE
    rgb_matrix_set_suspend_state(false);
#endif  // RGB_MATRIX_ENABLE
}

#ifdef RGB_MATRIX_ENABLE
void rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max) {
    // Turn on sideglow when CAPS LOCK is activated
    if (host_keyboard_led_state().caps_lock) {
        HSV hsv = {CAPS_LOCK_COLOR};
        hsv.v = rgb_matrix_get_val();
        RGB rgb = hsv_to_rgb(hsv);

        for (uint8_t i = led_min; i < led_max; i++) {
            if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
                RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
            }
        }
    }
}
#endif  // RGB_MATRIX_ENABLE

A keyboards/gmmk/pro/keymaps/mike1808/mike1808.h => keyboards/gmmk/pro/keymaps/mike1808/mike1808.h +111 -0
@@ 0,0 1,111 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */
#pragma once
#include QMK_KEYBOARD_H
#include "rgb_matrix_ledmaps.h"

enum layout_names {
    LINUX = 0,  // Base Layout: The main keyboard layout that has all the characters
    WINDOWS,    // Base ayout for Windows
    MACOS,      // Base Layout for MacOS
    FUNCTIONS,  // Function Layout: The function key activated layout with default functions and
                // some added ones
    GIT,        // GIT Layout: GIT shortcuts and macros
    SECRETS,    // Layer with secrets
};

enum custom_keycodes {
    KC_CCCV = SAFE_RANGE,  // Hold to copy, tap to paste
    KC_LINUX,
    KC_MAC,
    KC_WIN,

    KC_SECRET_1,
    KC_SECRET_2,
    KC_SECRET_3,
    KC_SECRET_4,
    KC_SECRET_5,

    KC_RGB_ENC_HUE,
    KC_RGB_ENC_SAT,
    KC_RGB_ENC_VAL,
    KC_RGB_ENC_EFFECT_SPEED,
    KC_RGB_ENC_EFFECT,

    KC_WPM_RGB,
};

enum git_macros {
    // The start of this enum should always be equal to end of ctrl_keycodes + 1
    G_INIT = KC_WPM_RGB + 1,  // git init
    G_CLONE,                  // git clone
    G_CONF,                   // git config --global
    G_ADD,                    // git add
    G_DIFF,                   // git diff
    G_RESET,                  // git reset
    G_REBAS,                  // git rebase
    G_BRANH,                  // git branch
    G_CHECK,                  // git checkout
    G_MERGE,                  // git merge
    G_REMTE,                  // git remote add
    G_FETCH,                  // git fetch
    G_PULL,                   // git pull
    G_PUSH,                   // git push
    G_COMM,                   // git commit
    G_STAT,                   // git status
    G_LOG,                    // git log
    NEW_SAFE_RANGE,
};

enum combos {
    JK_ESC,  // jk to ESC for Vim
};

#define KC_SEC1 KC_SECRET_1
#define KC_SEC2 KC_SECRET_2
#define KC_SEC3 KC_SECRET_3
#define KC_SEC4 KC_SECRET_4
#define KC_SEC5 KC_SECRET_5

#define KC_RGBH KC_RGB_ENC_HUE
#define KC_RGBS KC_RGB_ENC_SAT
#define KC_RGBV KC_RGB_ENC_VAL
#define KC_RGBE KC_RGB_ENC_EFFECT
#define KC_RGBP KC_RGB_ENC_EFFECT_SPEED

#define KC_WRGB KC_WPM_RGB

#define KC_LINX KC_LINUX

#define KC_RESET RESET
#define KC_RST KC_RESET

#define OS_GIT OSL(GIT)
#define TT_FN TT(FUNCTIONS)

#define OS_LGUI OSM(MOD_LGUI)
#define OS_RGUI OSM(MOD_RGUI)
#define OS_LSFT OSM(MOD_LSFT)
#define OS_RSFT OSM(MOD_RSFT)
#define OS_LCTL OSM(MOD_LCTL)
#define OS_RCTL OSM(MOD_RCTL)
#define OS_LALT OSM(MOD_LALT)
#define OS_RALT OSM(MOD_RALT)
#define OS_MEH OSM(MOD_MEH)
#define OS_HYPR OSM(MOD_HYPR)

#define CAPS_LOCK_COLOR HSV_RED


A keyboards/gmmk/pro/keymaps/mike1808/process_record.c => keyboards/gmmk/pro/keymaps/mike1808/process_record.c +119 -0
@@ 0,0 1,119 @@
/* Copyright 2021 Christopher Courtney, aka Drashna Jael're  (@drashna) <drashna@live.com>,
    Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "mike1808.h"
#include "print.h"
#include "process_record.h"

uint16_t copy_paste_timer;

__attribute__((weak)) bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
    return true;
}
__attribute__((weak)) bool process_record_encoder(uint16_t keycode, keyrecord_t *record) {
    return true;
}
__attribute__((weak)) bool process_record_fun(uint16_t keycode, keyrecord_t *record) {
    return true;
}

__attribute__((weak)) void keyboard_post_init_encoder(void) { return; }

static const char *git_commands[] = {
    "git init ",     "git clone ", "git config --global ", "git add ",
    "git diff ",     "git reset ", "git rebase ",          "git branch -b \"",
    "git checkout ", "git merge ", "git remote add ",      "git fetch ",
    "git pull ",     "git push ",  "git commit ",          "git status ",
    "git log ",
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
    // If console is enabled, it will print the matrix position and status of each key pressed
#ifdef KEYLOGGER_ENABLE
    uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %b, time: %5u, int: %b, count: %u\n",
            keycode, record->event.key.col, record->event.key.row, record->event.pressed,
            record->event.time, record->tap.interrupted, record->tap.count);
#endif  // KEYLOGGER_ENABLE
    switch (keycode) {
        case KC_LINUX ... KC_WIN:
            if (record->event.pressed) {
                dprintf("set_single_persistent_default_layer %d\n", keycode - KC_LINUX + LINUX);
                set_single_persistent_default_layer(keycode - KC_LINUX + LINUX);
                return false;
            }

            break;

        case KC_CCCV:  // One key copy/paste
            if (record->event.pressed) {
                copy_paste_timer = timer_read();
            } else {
                if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) {  // Hold, copy
                    if (layer_state_is(MACOS)) {
                        tap_code16(LGUI(KC_C));
                    } else {
                        tap_code16(LCTL(KC_C));
                    }
                } else {  // Tap, paste
                    if (layer_state_is(MACOS)) {
                        tap_code16(LGUI(KC_V));
                    } else {
                        tap_code16(LCTL(KC_V));
                    }
                }
            }
            break;

        case G_INIT ... G_LOG:
            if (record->event.pressed) {
                clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
                send_string_with_delay(git_commands[keycode - G_INIT], MACRO_TIMER);
                return false;
            }
            break;
#ifdef RGB_MATRIX_ENABLE
        case RGB_TOG:
            if (record->event.pressed) {
                switch (rgb_matrix_get_flags()) {
                    case LED_FLAG_ALL: {
                        rgb_matrix_set_flags(LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER);
                        rgb_matrix_set_color_all(0, 0, 0);
                    } break;
                    case LED_FLAG_KEYLIGHT | LED_FLAG_MODIFIER: {
                        rgb_matrix_set_flags(LED_FLAG_UNDERGLOW);
                        rgb_matrix_set_color_all(0, 0, 0);
                    } break;
                    case LED_FLAG_UNDERGLOW: {
                        // This line is for LED idle timer. It disables the toggle so you can turn
                        // off LED completely if you like
                        rgb_matrix_set_flags(LED_FLAG_NONE);
                        rgb_matrix_disable();
                    } break;
                    default: {
                        rgb_matrix_set_flags(LED_FLAG_ALL);
                        rgb_matrix_enable();
                    } break;
                }
            }
            return false;
#endif  // RGB_MATRIX_ENABLE
    }

    return process_record_encoder(keycode, record) && process_record_secrets(keycode, record) &&
           process_record_fun(keycode, record);
}

void keyboard_post_init_user() { keyboard_post_init_encoder(); }

A keyboards/gmmk/pro/keymaps/mike1808/process_record.h => keyboards/gmmk/pro/keymaps/mike1808/process_record.h +26 -0
@@ 0,0 1,26 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */
#pragma once
#include "mike1808.h"


bool process_record_secrets(uint16_t keycode, keyrecord_t *record);

bool process_record_encoder(uint16_t keycode, keyrecord_t *record);

bool process_record_fun(uint16_t keycode, keyrecord_t *record);

void keyboard_post_init_encoder(void);

A keyboards/gmmk/pro/keymaps/mike1808/rgb_matrix_ledmaps.c => keyboards/gmmk/pro/keymaps/mike1808/rgb_matrix_ledmaps.c +71 -0
@@ 0,0 1,71 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "rgb_matrix_ledmaps.h"

__attribute__((weak)) void rgb_matrix_indicators_keymap(void) { return; }
__attribute__((weak)) void rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max) {
    return;
}

#ifdef RGB_MATRIX_LEDMAPS_ENABLED

static bool enabled = true;

#endif  // RGB_MATRIX_LEDMAPS_ENABLED

void rgb_matrix_indicators_user(void) { rgb_matrix_indicators_keymap(); }
void rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
#ifdef RGB_MATRIX_LEDMAPS_ENABLED
    if (rgb_matrix_is_enabled() && enabled) {
        set_layer_rgb(led_min, led_max, get_highest_layer(layer_state | default_layer_state));
    }

#endif  // RGB_MATRIX_LEDMAPS_ENABLED
    rgb_matrix_indicators_advanced_keymap(led_min, led_max);
}

#ifdef RGB_MATRIX_LEDMAPS_ENABLED

void set_layer_rgb(uint8_t led_min, uint8_t led_max, int layer) {
    const ledmap *l = &(ledmaps[layer]);

    uint8_t val = rgb_matrix_get_val();

    for (int i = 0; i < DRIVER_LED_TOTAL; i++) {
        HSV hsv = {
            .h = (*l)[i][0],
            .s = (*l)[i][1],
            .v = val,
        };

        if (hsv.h || hsv.s) {
            RGB rgb = hsv_to_rgb(hsv);
            RGB_MATRIX_INDICATOR_SET_COLOR(i, rgb.r, rgb.g, rgb.b);
        }
    }
}

void rgb_matrix_layers_enable() {
    dprintf("ledmaps are enabled\n");
    enabled = true;
}

void rgb_matrix_layers_disable() {
    dprintf("ledmaps are disabled\n");
    enabled = false;
}

#endif  // RGB_MATRIX_LEDMAPS_ENABLED

A keyboards/gmmk/pro/keymaps/mike1808/rgb_matrix_ledmaps.h => keyboards/gmmk/pro/keymaps/mike1808/rgb_matrix_ledmaps.h +100 -0
@@ 0,0 1,100 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */
#pragma once

#include "quantum.h"

#ifdef RGB_MATRIX_LEDMAPS_ENABLED

// no association keycode
#    define XXX \
        { 0, 0, 0 }

// clang-format off
#   define RGB_MATRIX_LAYOUT_LEDMAP( \
        ul1,   k13, k26, k36, k31, k33, k07, k63, k71, k76, ka6, ka7, ka3, ka5, k97,     k01,   ur1, \
        ul2,   k16, k17, k27, k37, k47, k46, k56, k57, k67, k77, k87, k86, k66, ka1,     k65,   ur2, \
        ul3,   k11, k10, k20, k30, k40, k41, k51, k50, k60, k70, k80, k81, k61, ka2,     k15,   ur3, \
        ul4,   k21, k12, k22, k32, k42, k43, k53, k52, k62, k72, k82, k83,     ka4,      k25,   ur4, \
        ul5,   k00, k14, k24, k34, k44, k45, k55, k54, k64, k74, k85,    k91,       k35, k75,   ur5, \
        ul6,   k06,    k90,    k93,       k94,          k95,     k92, k04,     k03, k73, k05,   ur6 \
    ) \
    { \
        k13, k16, k11, k21, k00, k06, k26, k17, \
        k10, k12, k14, k90, k36, k27, k20, k22, \
        k24, k93, k31, k37, k30, k32, k34, k33, \
        k47, k40, k42, k44, k07, k46, k41, k43, \
        k45, k94, k63, k56, k51, k53, k55, k71, \
        k57, k50, k52, k54, k76, k67, k60, k62, \
        k64, k95, ka6, k77, k70, k72, k74, k92, \
        ka7, k87, k80, k82, k85, ka3, k86, k81, \
        k83, k04, ka5, ul1, ur1, k97, ul2, ur2, \
        k65, ul2, ur2, k15, ul3, ur3, k66, k05, \
        ul3, ur3, k75, ul4, ur4, ka1, k25, ul5, \
        ur5, k61, k91, ul6, ur6, ka2, k35, k03, \
        ka4, k73 \
    }
// clang-format on
typedef uint8_t ledmap[DRIVER_LED_TOTAL][3];
extern const ledmap ledmaps[];

void set_layer_rgb(uint8_t led_min, uint8_t led_max, int layer);

void rgb_matrix_layers_enable(void);
void rgb_matrix_layers_disable(void);

// Just a handy defines to make our ledmaps look better
#    define RED \
        { HSV_RED }
#    define CORAL \
        { HSV_CORAL }
#    define ORANGE \
        { HSV_ORANGE }
#    define GOLDEN \
        { HSV_GOLDENROD }
#    define GOLD \
        { HSV_GOLD }
#    define YELLOW \
        { HSV_YELLOW }
#    define CHART \
        { HSV_CHARTREUSE }
#    define GREEN \
        { HSV_GREEN }
#    define SPRING \
        { HSV_SPRINGGREEN }
#    define TURQ \
        { HSV_TURQUOISE }
#    define TEAL \
        { HSV_TEAL }
#    define CYAN \
        { HSV_CYAN }
#    define AZURE \
        { HSV_AZURE }
#    define BLUE \
        { HSV_BLUE }
#    define PURPLE \
        { HSV_PURPLE }
#    define MAGENT \
        { HSV_MAGENTA }
#    define PINK \
        { HSV_PINK }
#    define BLACK \
        { HSV_BLACK }

#endif  // RGB_MATRIX_LEDMAPS_ENABLED

void rgb_matrix_indicators_keymap(void);
void rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max);

A keyboards/gmmk/pro/keymaps/mike1808/rules.mk => keyboards/gmmk/pro/keymaps/mike1808/rules.mk +25 -0
@@ 0,0 1,25 @@
VIA_ENABLE = no

COMBO_ENABLE = yes
COMMAND_ENABLE = yes
RGB_MATRIX_ENABLE = yes
RAW_ENABLE = no
CONSOLE_ENABLE = yes

WPM_ENABLE = no

RGB_MATRIX_LEDMAPS = yes

SRC += utils.c
SRC += mike1808.c
SRC += process_record.c
SRC += encoder.c

ifeq ($(strip $(WPM_ENABLE)), yes)
	SRC += fun.c
endif

ifeq ($(strip $(RGB_MATRIX_LEDMAPS)), yes)
	SRC += rgb_matrix_ledmaps.c
	OPT_DEFS += -DRGB_MATRIX_LEDMAPS_ENABLED
endif

A keyboards/gmmk/pro/keymaps/mike1808/utils.c => keyboards/gmmk/pro/keymaps/mike1808/utils.c +64 -0
@@ 0,0 1,64 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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 "utils.h"

void store_rgb_state_to_eeprom() {
    uint8_t mode  = rgb_matrix_get_mode();
    uint8_t speed = rgb_matrix_get_speed();
    HSV     color = rgb_matrix_get_hsv();

    rgb_matrix_mode(mode);
    rgb_matrix_set_speed(speed);
    rgb_matrix_sethsv(color.h, color.s, color.v);
}

void press(KeyPressState *self) {
    self->_count++;

    dprintf("KPS: press: %d\n", self->_count);

    // pressed the first time
    if (self->_count == 1) {
        self->hander(true);
    }
}

void release(KeyPressState *self) {
    self->_count--;

    dprintf("KPS: release: %d\n", self->_count);

    // all keys are relased
    if (self->_count == 0) {
        self->hander(false);
    }
}

void reset(KeyPressState *self) {
    self->_count = 0;
}

KeyPressState *NewKeyPressState(key_press_handler handler) {
    KeyPressState *kps = (KeyPressState *)(malloc(sizeof(KeyPressState)));

    kps->_count = 0;
    kps->press = press;
    kps->release = release;
    kps->reset = reset;
    kps->hander = handler;

    return kps;
}

A keyboards/gmmk/pro/keymaps/mike1808/utils.h => keyboards/gmmk/pro/keymaps/mike1808/utils.h +32 -0
@@ 0,0 1,32 @@
/* Copyright 2021 Mikael Manukyan <arm.localhost@gmail.com>
 *
 * 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/>.
 */
#pragma once
#include "quantum.h"

void store_rgb_state_to_eeprom(void);

typedef void (*key_press_handler)(bool);

typedef struct KeyPressState KeyPressState;
struct KeyPressState {
        int _count;
        void (*press)(KeyPressState *self);
        void (*release)(KeyPressState *self);
        void (*reset)(KeyPressState *self);
        key_press_handler hander;
};

KeyPressState *NewKeyPressState(key_press_handler);