Piano / src / view /

piano-impl-view.c

/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "config.h"
#include "player/piano-impl.h"
#include "logger.h"
#include "piano-structs.h"
#include "view/piano-callbacks.h"
#include <efl_extension.h>

void piano_clear_win(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;
	if (ad->buttonList) {
		Eina_List *l = NULL;
		note_struct *note = NULL;
		EINA_LIST_FOREACH(ad->buttonList, l, note) {
			evas_object_del(note->button);
			note->button = NULL;
			free(note);
		}

		eina_list_free(ad->buttonList);
		ad->buttonList = NULL;
	}

	ecore_timer_del(ad->timer);
	ad->timer = NULL;
}

static void _createlayout(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	ad->win->layout = elm_layout_add(ad->win->win);

	elm_layout_file_set(ad->win->layout, get_path(THEME_PATH), "piano.layout");
	evas_object_size_hint_weight_set(ad->win->layout, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
	evas_object_size_hint_align_set(ad->win->layout, EVAS_HINT_FILL, EVAS_HINT_FILL);
	elm_win_resize_object_add(ad->win->win, ad->win->layout);
	evas_object_show(ad->win->layout);
}

static void _noteButton_fill(void *data, int index)
{
	RETM_IF(!data, "data is NULL");

	note_struct *note = (note_struct *)data;

	if (note->type == PIANO_NOTE_BLACK) {
		snprintf(note->sound_name, MAXNAMLEN, "black_%d.wav", index + 1);

		char part_name[MAXNAMLEN] = {'\0'};
		snprintf(part_name, MAXNAMLEN, "note_black_%d", index + 1);
		elm_object_part_content_set(note->ad->win->layout, part_name, note->button);

		elm_object_theme_set(note->button, note->ad->win->theme);
		elm_object_style_set(note->button, "circle/button_black");
	}

	if (note->type == PIANO_NOTE_WHITE) {
		snprintf(note->sound_name, MAXNAMLEN, "white_%d.wav", index + 1);

		char part_name[MAXNAMLEN] = {'\0'};
		snprintf(part_name, MAXNAMLEN, "note_white_%d", index + 1);
		elm_object_part_content_set(note->ad->win->layout, part_name, note->button);

		elm_object_theme_set(note->button, note->ad->win->theme);
		elm_object_style_set(note->button, "circle/button_white");
	}

	evas_object_show(note->button);
	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MULTI_DOWN, piano_note_touch_down_cb, note);
	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MULTI_UP, piano_note_touch_up_cb, note);

	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MOUSE_DOWN, piano_note_mouse_down_cb, note);
	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MOUSE_UP, piano_note_mouse_up_cb, note);

	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MOUSE_OUT, piano_note_mouse_out_cb, note);

	evas_object_event_callback_add(note->button, EVAS_CALLBACK_MOUSE_MOVE, piano_note_mouse_move_cb, note);

	piano_note_player_init(note);

	piano_note_player_prepare(note);

	evas_object_data_set(note->button, NOTE_BUTTON_DATA_KEY_NAME, note);

	note->ad->buttonList = eina_list_append(note->ad->buttonList, note);
}

static void _createBlackNotes(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	note_struct *prev_note = NULL;

	const int black_buttons_count = 6;

	for (int i = 0; i < black_buttons_count; i++) {
		note_struct *note = (note_struct *) calloc(1, sizeof(note_struct));
		RETM_IF(!note, "note is NULL");

		note->button = elm_button_add(ad->win->win);
		note->type = PIANO_NOTE_BLACK;
		note->ad = ad;
		note->prev = prev_note;

		if (prev_note) {
			prev_note->next = note;
		}

		_noteButton_fill(note, i);

		prev_note = note;
	}
}

static void _createWhiteNotes(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	note_struct *prev_note = NULL;

	const int white_buttons_count = 8;

	for (int i = 0; i < white_buttons_count; i++) {
		note_struct *note = (note_struct *)calloc(1, sizeof(note_struct));
		RETM_IF(!note, "note is NULL");

		note->button = elm_button_add(ad->win->win);
		note->type = PIANO_NOTE_WHITE;
		note->ad = ad;
		note->prev = prev_note;

		if (prev_note) {
			prev_note->next = note;
		}

		_noteButton_fill(note, i);

		prev_note = note;
	}
}

static void _noteButton_fill_rect(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	Eina_List *l = NULL;
	note_struct *note = NULL;
	EINA_LIST_FOREACH(ad->buttonList, l, note) {
		evas_object_geometry_get(note->button, &note->rect.x, &note->rect.y, &note->rect.w, &note->rect.h);
	}
}

static void _createnotes(void *data)
{
	RETM_IF(!data, "data is NULL");

	_createWhiteNotes(data);
	_createBlackNotes(data);

	_noteButton_fill_rect(data);
}

static void _applyTheme(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	ad->win->theme = elm_theme_new();
	if (ad->win->theme) {
		elm_theme_ref_set(ad->win->theme, NULL);
		elm_theme_extension_add(ad->win->theme, get_path(BUTTONS_STYLE_EDJ_PATH));
	}
}

static void _layout_back_cb(void *data, Evas_Object *obj, void *event_info)
{
	RETM_IF(!data, "data is NULL");

	app_data *application_data = (app_data *)data;

	elm_win_lower(application_data->win->win);
}

static void _registerKeyDown(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *application_data = (app_data *)data;

	eext_object_event_callback_add(application_data->win->layout, EEXT_CALLBACK_BACK, _layout_back_cb, application_data);
}

static void _createNoteTimer(void *data)
{
	RETM_IF(!data, "data is NULL");

	app_data *ad = (app_data *)data;

	const double delay = 0.3;

	ad->timer = ecore_timer_add(delay, piano_note_timer_cb, data);
}

void piano_createview(void *data)
{
	RETM_IF(!data, "data is NULL");

	_applyTheme(data);

	_createlayout(data);

	_createnotes(data);

	_registerKeyDown(data);

	_createNoteTimer(data);
}