1 /* 2 * Copyright (C) 2019-2020 Alexandros Theodotou <alex at zrythm dot org> 3 * 4 * This file is part of Zrythm 5 * 6 * Zrythm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero 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 * Zrythm 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 Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with this program. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * \file 22 * 23 * Digital meter used for displaying Position, 24 * BPM, etc. 25 */ 26 27 #ifndef __GUI_WIDGETS_DIGITAL_METER_H__ 28 #define __GUI_WIDGETS_DIGITAL_METER_H__ 29 30 #include <stdbool.h> 31 32 #include "audio/transport.h" 33 #include "utils/types.h" 34 35 #include <gtk/gtk.h> 36 37 #define DIGITAL_METER_WIDGET_TYPE \ 38 (digital_meter_widget_get_type ()) 39 G_DECLARE_FINAL_TYPE ( 40 DigitalMeterWidget, 41 digital_meter_widget, 42 Z, DIGITAL_METER_WIDGET, 43 GtkDrawingArea) 44 45 typedef enum NoteLength NoteLength; 46 typedef enum NoteType NoteType; 47 typedef struct Position Position; 48 49 /** 50 * @addtogroup widgets 51 * 52 * @{ 53 */ 54 55 typedef enum DigitalMeterType 56 { 57 DIGITAL_METER_TYPE_BPM, 58 DIGITAL_METER_TYPE_POSITION, 59 DIGITAL_METER_TYPE_TIMESIG, 60 DIGITAL_METER_TYPE_NOTE_TYPE, 61 DIGITAL_METER_TYPE_NOTE_LENGTH, 62 } DigitalMeterType; 63 64 typedef struct SnapGrid SnapGrid; 65 66 typedef struct _DigitalMeterWidget 67 { 68 GtkDrawingArea parent_instance; 69 70 DigitalMeterType type; 71 72 bool is_transport; 73 74 GtkGestureDrag * drag; 75 double last_y; 76 double last_x; 77 int height_start_pos; 78 int height_end_pos; 79 80 /* ========= BPM ========= */ 81 /* for BPM */ 82 int num_part_start_pos; 83 int num_part_end_pos; 84 int dec_part_start_pos; 85 int dec_part_end_pos; 86 87 /** Used when changing the BPM. */ 88 bpm_t bpm_at_start; 89 90 /** Used during update. */ 91 bpm_t last_set_bpm; 92 93 /** Flag to update BPM. */ 94 bool update_num; 95 /** Flag to update BPM decimal. */ 96 bool update_dec; 97 98 /* ========= BPM end ========= */ 99 100 /* ========= position ========= */ 101 102 int bars_start_pos; 103 int bars_end_pos; 104 int beats_start_pos; 105 int beats_end_pos; 106 int sixteenths_start_pos; 107 int sixteenths_end_pos; 108 int ticks_start_pos; 109 int ticks_end_pos; 110 111 /** Update flags. */ 112 int update_bars; 113 int update_beats; 114 int update_sixteenths; 115 int update_ticks; 116 117 /* ========= position end ========= */ 118 119 /* ========= time ========= */ 120 121 /** For time. */ 122 int minutes_start_pos; 123 int minutes_end_pos; 124 int seconds_start_pos; 125 int seconds_end_pos; 126 int ms_start_pos; 127 int ms_end_pos; 128 129 /** Update flags. */ 130 int update_minutes; 131 int update_seconds; 132 int update_ms; 133 134 /* ========= time end ========= */ 135 136 /* for note length/type */ 137 NoteLength * note_length; 138 NoteType * note_type; 139 int update_note_length; ///< flag to update note length 140 int start_note_length; ///< start note length 141 int update_note_type; ///< flag to update note type 142 int start_note_type; ///< start note type 143 144 /* for time sig */ 145 int update_timesig_top; 146 /* ebeat unit */ 147 int update_timesig_bot; 148 149 /** Used when changing the time signature. */ 150 int beats_per_bar_at_start; 151 int beat_unit_at_start; 152 153 /* ---------- FOR POSITION ---------------- */ 154 void * obj; 155 156 /** Getter for Position. */ 157 void (*getter)(void*, Position*); 158 /** Setter for Position. */ 159 void (*setter)(void*, Position*); 160 /** Function to call on drag begin. */ 161 void (*on_drag_begin)(void*); 162 /** Function to call on drag end. */ 163 void (*on_drag_end)(void*); 164 165 /* ----------- position end --------------- */ 166 167 /** Draw line above the meter or not. */ 168 int draw_line; 169 170 /** Caption to show above, NULL to not show. */ 171 char * caption; 172 173 /** Cached layouts for drawing text. */ 174 PangoLayout * caption_layout; 175 PangoLayout * seg7_layout; 176 PangoLayout * normal_layout; 177 } DigitalMeterWidget; 178 179 /** 180 * Creates a digital meter with the given type ( 181 * bpm or position). 182 */ 183 DigitalMeterWidget * 184 digital_meter_widget_new ( 185 DigitalMeterType type, 186 NoteLength * note_length, 187 NoteType * note_type, 188 const char * caption); 189 190 191 #define digital_meter_widget_new_for_position( \ 192 obj,drag_begin,getter,setter,drag_end,caption) \ 193 _digital_meter_widget_new_for_position ( \ 194 (void *) obj, \ 195 (void (*) (void *)) drag_begin, \ 196 (void (*) (void *, Position *)) getter, \ 197 (void (*) (void *, Position *)) setter, \ 198 (void (*) (void *)) drag_end, \ 199 caption) 200 201 /** 202 * Creates a digital meter for an arbitrary position. 203 * 204 * @param obj The object to call the get/setters with. 205 * 206 * E.g. Region. 207 * @param get_val The getter func to get the position, 208 * passing the obj and the position to save to. 209 * @param set_val The setter function to set the 210 * position. 211 * @param drag_begin Function to call when 212 * starting the action. 213 * @parram drag_end Function to call when ending 214 * the action. 215 */ 216 DigitalMeterWidget * 217 _digital_meter_widget_new_for_position( 218 void * obj, 219 void (*drag_begin)(void *), 220 void (*get_val)(void *, Position *), 221 void (*set_val)(void *, Position *), 222 void (*drag_end)(void *), 223 const char * caption); 224 225 void 226 digital_meter_set_draw_line ( 227 DigitalMeterWidget * self, 228 int draw_line); 229 230 /** 231 * @} 232 */ 233 234 #endif 235