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