]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/infinity_ergodox/keymaps/default/visualizer.c
Merge pull request #584 from algernon/ergodox-ez/algernon
[qmk_firmware.git] / keyboards / infinity_ergodox / keymaps / default / visualizer.c
1 /*
2 Copyright 2016 Fred Sundvik <fsundvik@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 // Currently we are assuming that both the backlight and LCD are enabled
19 // But it's entirely possible to write a custom visualizer that use only
20 // one of them
21 #ifndef LCD_BACKLIGHT_ENABLE
22 #error This visualizer needs that LCD backlight is enabled
23 #endif
24
25 #ifndef LCD_ENABLE
26 #error This visualizer needs that LCD is enabled
27 #endif
28
29 #include "visualizer.h"
30 #include "led_test.h"
31
32 static const char* welcome_text[] = {"TMK", "Infinity Ergodox"};
33
34 // Just an example how to write custom keyframe functions, we could have moved
35 // all this into the init function
36 bool display_welcome(keyframe_animation_t* animation, visualizer_state_t* state) {
37     (void)animation;
38     // Read the uGFX documentation for information how to use the displays
39     // http://wiki.ugfx.org/index.php/Main_Page
40     gdispClear(White);
41     // You can use static variables for things that can't be found in the animation
42     // or state structs
43     gdispDrawString(0, 3, welcome_text[0], state->font_dejavusansbold12, Black);
44     gdispDrawString(0, 15, welcome_text[1], state->font_dejavusansbold12, Black);
45     // Always remember to flush the display
46     gdispFlush();
47     // you could set the backlight color as well, but we won't do it here, since
48     // it's part of the following animation
49     // lcd_backlight_color(hue, saturation, intensity);
50     // We don't need constant updates, just drawing the screen once is enough
51     return false;
52 }
53
54 // Feel free to modify the animations below, or even add new ones if needed
55
56 // Don't worry, if the startup animation is long, you can use the keyboard like normal
57 // during that time
58 static keyframe_animation_t startup_animation = {
59     .num_frames = 4,
60     .loop = false,
61     .frame_lengths = {0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0},
62     .frame_functions = {
63             display_welcome,
64             keyframe_animate_backlight_color,
65             keyframe_no_operation,
66             enable_visualization
67     },
68 };
69
70 // The color animation animates the LCD color when you change layers
71 static keyframe_animation_t color_animation = {
72     .num_frames = 2,
73     .loop = false,
74     // Note that there's a 200 ms no-operation frame,
75     // this prevents the color from changing when activating the layer
76     // momentarily
77     .frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)},
78     .frame_functions = {keyframe_no_operation, keyframe_animate_backlight_color},
79 };
80
81 // The LCD animation alternates between the layer name display and a
82 // bitmap that displays all active layers
83 static keyframe_animation_t lcd_animation = {
84     .num_frames = 2,
85     .loop = true,
86     .frame_lengths = {gfxMillisecondsToTicks(2000), gfxMillisecondsToTicks(2000)},
87     .frame_functions = {keyframe_display_layer_text, keyframe_display_layer_bitmap},
88 };
89
90 static keyframe_animation_t suspend_animation = {
91     .num_frames = 3,
92     .loop = false,
93     .frame_lengths = {0, gfxMillisecondsToTicks(1000), 0},
94     .frame_functions = {
95             keyframe_display_layer_text,
96             keyframe_animate_backlight_color,
97             keyframe_disable_lcd_and_backlight,
98     },
99 };
100
101 static keyframe_animation_t resume_animation = {
102     .num_frames = 5,
103     .loop = false,
104     .frame_lengths = {0, 0, gfxMillisecondsToTicks(1000), gfxMillisecondsToTicks(5000), 0},
105     .frame_functions = {
106             keyframe_enable_lcd_and_backlight,
107             display_welcome,
108             keyframe_animate_backlight_color,
109             keyframe_no_operation,
110             enable_visualization,
111     },
112 };
113
114 void initialize_user_visualizer(visualizer_state_t* state) {
115     // The brightness will be dynamically adjustable in the future
116     // But for now, change it here.
117     lcd_backlight_brightness(0x50);
118     state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0xFF);
119     state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF);
120     start_keyframe_animation(&startup_animation);
121     start_keyframe_animation(&led_test_animation);
122 }
123
124 void update_user_visualizer_state(visualizer_state_t* state) {
125     // Add more tests, change the colors and layer texts here
126     // Usually you want to check the high bits (higher layers first)
127     // because that's the order layers are processed for keypresses
128     // You can for check for example:
129     // state->status.layer
130     // state->status.default_layer
131     // state->status.leds (see led.h for available statuses)
132     if (state->status.layer & 0x8) {
133         state->target_lcd_color = LCD_COLOR(0xC0, 0xB0, 0xFF);
134         state->layer_text = "Numpad";
135     }
136     else if (state->status.layer & 0x4) {
137         state->target_lcd_color = LCD_COLOR(0, 0xB0, 0xFF);
138         state->layer_text = "KBD functions";
139     }
140     else if (state->status.layer & 0x2) {
141         state->target_lcd_color = LCD_COLOR(0x80, 0xB0, 0xFF);
142         state->layer_text = "Function keys";
143     }
144     else {
145         state->target_lcd_color = LCD_COLOR(0x40, 0xB0, 0xFF);
146         state->layer_text = "Default";
147     }
148     // You can also stop existing animations, and start your custom ones here
149     // remember that you should normally have only one animation for the LCD
150     // and one for the background. But you can also combine them if you want.
151     start_keyframe_animation(&lcd_animation);
152     start_keyframe_animation(&color_animation);
153 }
154
155 void user_visualizer_suspend(visualizer_state_t* state) {
156     state->layer_text = "Suspending...";
157     uint8_t hue = LCD_HUE(state->current_lcd_color);
158     uint8_t sat = LCD_SAT(state->current_lcd_color);
159     state->target_lcd_color = LCD_COLOR(hue, sat, 0);
160     start_keyframe_animation(&suspend_animation);
161 }
162
163 void user_visualizer_resume(visualizer_state_t* state) {
164     state->current_lcd_color = LCD_COLOR(0x00, 0x00, 0x00);
165     state->target_lcd_color = LCD_COLOR(0x10, 0xFF, 0xFF);
166     start_keyframe_animation(&resume_animation);
167     start_keyframe_animation(&led_test_animation);
168 }