2 Calf Box, an open source musical instrument.
3 Copyright (C) 2010-2011 Krzysztof Foltman
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /*******************************************************************/
26 static void item_measure(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
)
28 struct cbox_menu_measure
*m
= &state
->size
;
29 gchar
*value
= item
->item_class
->format_value(item
, state
);
31 int len
= strlen(item
->label
);
32 int len2
= value
? strlen(value
) : 0;
33 if (len
> m
->label_width
)
35 if (len2
> m
->value_width
)
36 m
->value_width
= len2
;
42 static void item_destroy(struct cbox_menu_item
*item
)
48 static void item_draw(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
, gchar
*value
, int hilited
)
50 int y
= item
->y
- state
->yoffset
;
51 if (y
< 1 || y
> state
->yspace
)
54 wattron(state
->window
, A_REVERSE
);
55 mvwprintw(state
->window
, item
->y
- state
->yoffset
, item
->x
, "%-*s %*s", state
->size
.label_width
, item
->label
, state
->size
.value_width
, value
);
56 wattroff(state
->window
, A_REVERSE
);
59 /*******************************************************************/
61 static gchar
*command_format(const struct cbox_menu_item
*item
, struct cbox_menu_state
*state
)
66 static int command_on_key(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
, int key
)
70 struct cbox_menu_item_command
*citem
= (struct cbox_menu_item_command
*)item
;
71 return citem
->execute(citem
, state
->context
);
76 struct cbox_menu_item_class menu_item_class_command
= {
77 .measure
= item_measure
,
79 .format_value
= command_format
,
81 .on_key
= command_on_key
,
82 .destroy
= item_destroy
85 /*******************************************************************/
87 void static_draw(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
, gchar
*value
, int hilited
)
89 int y
= item
->y
- state
->yoffset
;
90 if (y
< 1 || y
> state
->yspace
)
94 wattron(state
->window
, A_BOLD
);
95 mvwprintw(state
->window
, y
, item
->x
, "%-*s", state
->size
.label_width
+ state
->size
.value_width
, item
->label
);
96 wattroff(state
->window
, A_BOLD
);
99 mvwprintw(state
->window
, y
, item
->x
, "%-*s %*s", state
->size
.label_width
, item
->label
, state
->size
.value_width
, value
);
102 static gchar
*static_format(const struct cbox_menu_item
*item
, struct cbox_menu_state
*state
)
104 struct cbox_menu_item_static
*sitem
= (struct cbox_menu_item_static
*)item
;
105 if (!sitem
->format_value
)
107 return sitem
->format_value(sitem
, state
->context
);
110 struct cbox_menu_item_class menu_item_class_static
= {
111 .measure
= item_measure
,
113 .format_value
= static_format
,
116 .destroy
= item_destroy
119 /*******************************************************************/
121 static gchar
*intvalue_format(const struct cbox_menu_item
*item
, struct cbox_menu_state
*state
)
123 struct cbox_menu_item_int
*iitem
= (struct cbox_menu_item_int
*)item
;
125 return g_strdup_printf("%d", *iitem
->value
);
128 static int intvalue_on_key(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
, int key
)
130 struct cbox_menu_item_int
*iitem
= (struct cbox_menu_item_int
*)item
;
137 if (*pv
> iitem
->vmin
)
140 if (iitem
->on_change
)
141 iitem
->on_change(iitem
, state
->context
);
147 if (*pv
< iitem
->vmax
)
150 if (iitem
->on_change
)
151 iitem
->on_change(iitem
, state
->context
);
159 struct cbox_menu_item_class menu_item_class_int
= {
160 .measure
= item_measure
,
162 .format_value
= intvalue_format
,
164 .on_key
= intvalue_on_key
,
165 .destroy
= item_destroy
169 /*******************************************************************/
171 static gchar
*menu_format(const struct cbox_menu_item
*item
, struct cbox_menu_state
*state
)
173 struct cbox_menu_item_menu
*mitem
= (struct cbox_menu_item_menu
*)item
;
175 return g_strdup((mitem
->menu
|| mitem
->create_menu
) ? "->" : "<-");
178 static int menu_on_key(struct cbox_menu_item
*item
, struct cbox_menu_state
*state
, int key
)
182 struct cbox_menu_item_menu
*mitem
= (struct cbox_menu_item_menu
*)item
;
183 if (mitem
->create_menu
)
185 struct cbox_menu_state
*new_state
= cbox_menu_state_new(state
->page
, mitem
->create_menu(mitem
, state
->context
), state
->window
, state
->context
);
186 new_state
->caller
= state
;
187 state
->page
->state
= new_state
;
192 struct cbox_menu_state
*new_state
= cbox_menu_state_new(state
->page
, mitem
->menu
, state
->window
, state
->context
);
193 new_state
->caller
= state
;
194 state
->page
->state
= new_state
;
198 struct cbox_menu_state
*old_state
= state
;
199 state
->page
->state
= state
->caller
;
200 if (old_state
->menu_is_temporary
)
201 cbox_menu_destroy(old_state
->menu
);
202 cbox_menu_state_destroy(old_state
);
210 struct cbox_menu_item_class menu_item_class_menu
= {
211 .measure
= item_measure
,
213 .format_value
= menu_format
,
215 .on_key
= menu_on_key
,
216 .destroy
= item_destroy
219 /*******************************************************************/
221 struct cbox_menu_item
*cbox_menu_item_new_command(const char *label
, cbox_menu_item_execute_func exec
, void *item_context
)
223 struct cbox_menu_item_command
*item
= malloc(sizeof(struct cbox_menu_item_command
));
224 item
->item
.label
= g_strdup(label
);
225 item
->item
.item_class
= &menu_item_class_command
;
226 item
->item
.item_context
= item_context
;
227 item
->execute
= exec
;
231 struct cbox_menu_item
*cbox_menu_item_new_static(const char *label
, cbox_menu_item_format_value fmt
, void *item_context
)
233 struct cbox_menu_item_static
*item
= malloc(sizeof(struct cbox_menu_item_static
));
234 item
->item
.label
= g_strdup(label
);
235 item
->item
.item_class
= &menu_item_class_static
;
236 item
->item
.item_context
= item_context
;
237 item
->format_value
= fmt
;
241 struct cbox_menu_item
*cbox_menu_item_new_int(const char *label
, int *value
, int vmin
, int vmax
, void *item_context
)
243 struct cbox_menu_item_int
*item
= malloc(sizeof(struct cbox_menu_item_int
));
244 item
->item
.label
= g_strdup(label
);
245 item
->item
.item_class
= &menu_item_class_int
;
246 item
->item
.item_context
= item_context
;
250 item
->on_change
= NULL
;
254 struct cbox_menu_item
*cbox_menu_item_new_menu(const char *label
, struct cbox_menu
*menu
, void *item_context
)
256 struct cbox_menu_item_menu
*item
= malloc(sizeof(struct cbox_menu_item_menu
));
257 item
->item
.label
= g_strdup(label
);
258 item
->item
.item_class
= &menu_item_class_menu
;
259 item
->item
.item_context
= item_context
;
261 item
->create_menu
= NULL
;
265 struct cbox_menu_item
*cbox_menu_item_new_dynamic_menu(const char *label
, create_menu_func func
, void *item_context
)
267 struct cbox_menu_item_menu
*item
= malloc(sizeof(struct cbox_menu_item_menu
));
268 item
->item
.label
= g_strdup(label
);
269 item
->item
.item_class
= &menu_item_class_menu
;
270 item
->item
.item_context
= item_context
;
272 item
->create_menu
= func
;
276 void cbox_menu_item_destroy(struct cbox_menu_item
*item
)
278 item
->item_class
->destroy(item
);