1 /*
2 * Copyright (C) 2018-2019 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 Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "audio/chord_object.h"
21 #include "audio/chord_track.h"
22 #include "gui/widgets/arranger.h"
23 #include "gui/widgets/bot_bar.h"
24 #include "gui/widgets/arranger_object.h"
25 #include "gui/widgets/chord_object.h"
26 #include "gui/widgets/chord_selector_window.h"
27 #include "project.h"
28 #include "utils/cairo.h"
29 #include "utils/ui.h"
30 #include "zrythm_app.h"
31
32 #include <glib/gi18n.h>
33
34 /**
35 * Recreates the pango layouts for drawing.
36 *
37 * @param width Full width of the marker.
38 */
39 void
chord_object_recreate_pango_layouts(ChordObject * self)40 chord_object_recreate_pango_layouts (
41 ChordObject * self)
42 {
43 ArrangerObject * obj = (ArrangerObject *) self;
44
45 if (!PANGO_IS_LAYOUT (self->layout))
46 {
47 PangoFontDescription *desc;
48 self->layout =
49 gtk_widget_create_pango_layout (
50 GTK_WIDGET (
51 arranger_object_get_arranger (obj)),
52 NULL);
53 desc =
54 pango_font_description_from_string (
55 CHORD_OBJECT_NAME_FONT);
56 pango_layout_set_font_description (
57 self->layout, desc);
58 pango_font_description_free (desc);
59 }
60 pango_layout_get_pixel_size (
61 self->layout, &obj->textw, &obj->texth);
62 }
63
64 /**
65 *
66 * @param cr Cairo context of the arranger.
67 * @param rect Rectangle in the arranger.
68 */
69 void
chord_object_draw(ChordObject * self,cairo_t * cr,GdkRectangle * rect)70 chord_object_draw (
71 ChordObject * self,
72 cairo_t * cr,
73 GdkRectangle * rect)
74 {
75 ArrangerObject * obj = (ArrangerObject *) self;
76 ArrangerWidget * arranger =
77 arranger_object_get_arranger (obj);
78
79 /* get color */
80 GdkRGBA color = P_CHORD_TRACK->color;
81 ui_get_arranger_object_color (
82 &color,
83 arranger->hovered_object == obj,
84 chord_object_is_selected (self), false, false);
85 ChordDescriptor * descr =
86 chord_object_get_chord_descriptor (self);
87 gdk_cairo_set_source_rgba (cr, &color);
88
89 z_cairo_rounded_rectangle (
90 cr,
91 obj->full_rect.x - rect->x,
92 obj->full_rect.y - rect->y,
93 obj->full_rect.width,
94 obj->full_rect.height, 1, 4);
95 cairo_fill (cr);
96
97 char str[100];
98 chord_descriptor_to_string (descr, str);
99 char display_str[200];
100 if (DEBUGGING)
101 {
102 sprintf (
103 display_str, "%d %s",
104 self->chord_index, str);
105 }
106 else
107 {
108 strcpy (display_str, str);
109 }
110
111 GdkRGBA c2;
112 ui_get_contrast_color (&color, &c2);
113 gdk_cairo_set_source_rgba (cr, &c2);
114 cairo_move_to (
115 cr,
116 (obj->full_rect.x + CHORD_OBJECT_NAME_PADDING) -
117 rect->x,
118 (obj->full_rect.y + CHORD_OBJECT_NAME_PADDING) -
119 rect->y);
120 z_cairo_draw_text (
121 cr, GTK_WIDGET (arranger), self->layout,
122 display_str);
123 }
124
125 #if 0
126 static void
127 on_press (
128 GtkGestureMultiPress *gesture,
129 gint n_press,
130 gdouble x,
131 gdouble y,
132 ChordObjectWidget * self)
133 {
134 if (n_press == 2)
135 {
136 ChordSelectorWindowWidget * chord_selector =
137 chord_selector_window_widget_new (
138 chord_object_get_chord_descriptor (
139 self->chord_object));
140
141 gtk_window_present (
142 GTK_WINDOW (chord_selector));
143 }
144 }
145
146 ChordObjectWidget *
147 chord_object_widget_new (ChordObject * chord)
148 {
149 ChordObjectWidget * self =
150 g_object_new (CHORD_OBJECT_WIDGET_TYPE, NULL);
151
152 arranger_object_widget_setup (
153 Z_ARRANGER_OBJECT_WIDGET (self),
154 (ArrangerObject *) chord);
155
156 self->chord_object = chord;
157
158 return self;
159 }
160
161 static void
162 finalize (
163 ChordObjectWidget * self)
164 {
165 if (self->mp)
166 g_object_unref (self->mp);
167
168 G_OBJECT_CLASS (
169 chord_object_widget_parent_class)->
170 finalize (G_OBJECT (self));
171 }
172
173 static void
174 chord_object_widget_class_init (
175 ChordObjectWidgetClass * _klass)
176 {
177 GtkWidgetClass * klass =
178 GTK_WIDGET_CLASS (_klass);
179 GObjectClass * oklass = G_OBJECT_CLASS (klass);
180 oklass->finalize =
181 (GObjectFinalizeFunc) finalize;
182 }
183
184 static void
185 chord_object_widget_init (
186 ChordObjectWidget * self)
187 {
188 ARRANGER_OBJECT_WIDGET_GET_PRIVATE (self);
189
190 self->mp =
191 GTK_GESTURE_MULTI_PRESS (
192 gtk_gesture_multi_press_new (
193 GTK_WIDGET (ao_prv->drawing_area)));
194
195 g_signal_connect (
196 G_OBJECT (ao_prv->drawing_area), "draw",
197 G_CALLBACK (chord_draw_cb), self);
198 g_signal_connect (
199 G_OBJECT (self->mp), "pressed",
200 G_CALLBACK (on_press), self);
201 }
202 #endif
203