ステップ 4 - ウィジェットを選択するためのインタラクションハンドラを作成する¶
このチュートリアルでは、Widget Grid List Box に含まれるウィジェットのリストをユーザーがスクロールし、そのリストから Widget Item Prefab で表されるウィジェットを選択できるアプリケーションを作成します。Grid List Box 3D ノードは Kanzi Studio プロジェクトで設定できる水平スクロールを提供しますが、ウィジェットの選択を処理するアプリケーションロジックを定義する必要があります。
このチュートリアルのこのステップでは、ユーザーがウィジェットをクリックしたときにウィジェットアイテムの選択を処理する機能を実装します。
カメラをズームして、選択されたウィジェットがアプリケーションウィンドウの左側でハイライトされる位置にするアニメーションをトリガーします。
選択したウィジェットをカメラに向けて強調表示するアニメーションをトリガーします。
アプリケーションウィンドウの右側にある Widget Description Layer ノードで表される説明パネルを表示します。説明パネルには、各ウィジェットの説明、戻るボタン、および購入ボタンが含まれています。Widget Description Layer が表示されているときは、Widget Grid List Box のスクロールが無効になります。カメラズームアニメーションが進行中の場合、Back ボタンは無効になります。
ウィジェットを選択するためのインタラクションハンドラを作成するには:
ProgrammerTutorialApplicationクラス内で、Application::onProjectLoaded関数の後に、Widget Grid List Box でウィジェットを選択するためのイベントハンドラを実装します。選択されたウィジェットのインデックスを使用して、Widget Grid List Box ノードから選択されたウィジェットを取得します。class ProgrammerTutorialApplication : public ExampleApplication { ... private: // The handler for the ListBox.ItemSelected message from the Widget Grid List Box. // Brings the selected list box item to the front. void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { // Retrieve the index of the selected list box item from the message arguments. optional<size_t> selectedItemIndex = messageArguments.getSelectedItemIndex(); if (selectedItemIndex) { // Remove old playbacks to reset the values. // You implement this function in the next step of the tutorial. removePlaybacks(); // Retrieve the selected list box item by its index. m_selectedItem = m_widgetList->getItem(*selectedItemIndex); ... } } };
ターゲットアニメーションはカメラを再配置します。アニメーションはノードの現在の変換を取得し、別のノードによって定義された別の変換にアニメーションします。現在、保存されているカメラの変換は、選択されたウィジェットの変換で更新されます。カメラ用のアニメーションを作成し、アニメーションを開始します。
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... // Calculate a new value for the camera animation target node and start the animation. { // Get the current transformation. Matrix4x4 selectedItemTransformation = m_selectedItem->getFinalTransformation(); // Get the camera's relative transformation target position. SRTValue3D transformationTarget = m_cameraTransformationTarget; // Add the position of the selected item to the target camera transformation. transformationTarget.setTranslation(selectedItemTransformation.getTranslation() - transformationTarget.getTranslation()); // Create the animation for the camera. m_cameraAnimation = FromToAnimation<SRTValue3D, LinearEasingFunction>::create(getDomain(), chrono::seconds(1), nullopt, transformationTarget); // Start the animation. PropertyAnimationTimelineSharedPtr cameraTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Node3D::RenderTransformationProperty, m_cameraAnimation); SceneGraphTimelinePlaybackContext cameraContext(*m_camera); m_cameraPlayback = cameraTimeline->createPlayback(cameraContext); getDomain()->getRootTimelineClock()->addTimelinePlayback(m_cameraPlayback); } } ... }
Camera アニメーションの変換ターゲットが更新されたので、選択されたウィジェットのハイライトアニメーションを開始できます。ハイライトアニメーションは、ウィジェットを x 軸を中心に固定値 0 から 60 度まで回転させ、
Application::onProjectLoaded関数で定義されています。void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... // Start the animation for the selected item. PropertyAnimationTimelineSharedPtr selectedItemTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Node3D::LayoutTransformationProperty, m_selectedItemAnimation); SceneGraphTimelinePlaybackContext selectedItemContext(*m_selectedItem); m_widgetHighlightPlayback = selectedItemTimeline->createPlayback(selectedItemContext); getDomain()->getRootTimelineClock()->addTimelinePlayback(m_widgetHighlightPlayback); } }
アニメーションが開始されるときに、Back button の入力を無効にします。
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... // Start the animation to disable input for the Back button. PropertyAnimationTimelineSharedPtr backButtonEnableTimeline = PropertyAnimationTimeline::create(getDomain(), ".", Button3D::HitTestableProperty, m_backButtonEnableAnimation); SceneGraphTimelinePlaybackContext backButtonEnableContext(*m_backButton); m_backButtonEnablePlayback = backButtonEnableTimeline->createPlayback(backButtonEnableContext); getDomain()->getRootTimelineClock()->addTimelinePlayback(m_backButtonEnablePlayback); } }
Programmertutorial.WidgetDescription プロパティからウィジェットの説明を取得し、Text Block 2D ノードの Text プロパティの値を Programmertutorial.WidgetDescription プロパティの値に設定し、アプリケーションウィンドウの右側にあるパネルを含む Widget Description Layer を表示します。
void onListBoxItemSelected(ListBoxConcept::ItemSelectedMessageArguments& messageArguments) { ... if (selectedItemIndex) { ... // Show the widget description by setting the Widget Description Layer visible. if (m_widgetDescriptionVisibilityPlayback) { getDomain()->getRootTimelineClock()->removeTimelinePlayback(*m_widgetDescriptionVisibilityPlayback); m_widgetDescriptionVisibilityPlayback.reset(); } // Set the widget description to the description text. The description is taken from the widget node. string widgetDescription = m_selectedItem->getProperty(*m_widgetDescriptionPropertyType); m_widgetDescriptionTextBlock->setText(widgetDescription); // Set the Widget Description Layer visible. m_widgetDescriptionNode->setVisible(true); } }
Application::onProjectLoaded関数で、ウィジェットリストを埋めた後に Widget Grid List Box ノードのListBoxConcept::ItemSelectedMessageのメッセージハンドラを登録します。void onProjectLoaded() override { ... // Add a message handler for selecting the Grid List Box 3D item events. m_widgetList->addMessageHandler(GridListBox3D::ItemSelectedMessage, bind(&ProgrammerTutorialApplication::onListBoxItemSelected, this, placeholders::_1)); }
ウィジェットをクリックすると、アプリケーションは指定した2つのアニメーションを使用してウィジェットをハイライトし、Widget Description Layer ノードを表示し、Widget Description Layer にウィジェットの説明を表示します。