1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     SmButton.cpp
4 
5   Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain proprietary
8   information of Nintendo and/or its licensed developers and are protected by
9   national and international copyright laws. They may not be disclosed to third
10   parties or copied or duplicated in any form, in whole or in part, without the
11   prior written consent of Nintendo.
12 
13   The content herein is highly confidential and should be handled accordingly.
14 
15   $Revision: $
16  *---------------------------------------------------------------------------*/
17 #include <nn/os.h>
18 
19 #include <nw/types.h>
20 #include <nw/ut.h>
21 
22 #include "../include/SmButton.h"
23 #include "../include/SmTouchPanelStatus.h"
24 
25 namespace
26 {
27 
28 //----------------------------------------
29 // コンストラクタ
SmButton(uint x,uint y,uint w,uint h)30 SmButton::SmButton( uint x, uint y, uint w, uint h )
31 : SmMessage( NULL ),
32   m_Button( NULL ),
33   m_PushButton( NULL ),
34   m_IsPressed( false ),
35   m_IsGrab( false ),
36   m_IsSwitch( true ),
37   m_OnColor( nw::ut::Color8::BLACK ),
38   m_OffColor( nw::ut::Color8::RED )
39 {
40     NW_NULL_ASSERT( m_Allocator );
41 
42     // ボタンポリゴン生成
43     m_Button = new Sm2DPrimPC( 4 );
44     NW_NULL_ASSERT( m_Button );
45     {
46         m_Button->SetVertex( 0, x,      y,      nw::ut::Color8::BLACK );
47         m_Button->SetVertex( 1, x,      y + h,  nw::ut::Color8::BLACK );
48         m_Button->SetVertex( 2, x + w,  y,      nw::ut::Color8::BLACK );
49         m_Button->SetVertex( 3, x + w,  y + h,  nw::ut::Color8::BLACK );
50     }
51     m_Button->Update();
52 
53     // 押されたボタンポリゴン生成
54     #define PRESSED_BTN_MARGIN  (4.f)
55     m_PushButton = new Sm2DPrimPC( 4 );
56     NW_NULL_ASSERT( m_PushButton );
57     {
58         m_PushButton->SetVertex( 0, x - PRESSED_BTN_MARGIN,      y - PRESSED_BTN_MARGIN,      nw::ut::Color8::YELLOW );
59         m_PushButton->SetVertex( 1, x - PRESSED_BTN_MARGIN,      y + h + PRESSED_BTN_MARGIN,  nw::ut::Color8::YELLOW );
60         m_PushButton->SetVertex( 2, x + w + PRESSED_BTN_MARGIN,  y - PRESSED_BTN_MARGIN,      nw::ut::Color8::YELLOW );
61         m_PushButton->SetVertex( 3, x + w + PRESSED_BTN_MARGIN,  y + h + PRESSED_BTN_MARGIN,  nw::ut::Color8::YELLOW );
62     }
63     m_PushButton->Update();
64 
65     // コリジョン形状を登録
66     m_Collision.SetRect( x, y, w, h );
67 
68     // 初期状態
69     SetSwitch( m_IsSwitch );
70 }
71 
72 
73 //----------------------------------------
74 // デストラクタ
~SmButton()75 SmButton::~SmButton()
76 {
77     if ( m_Button ) delete m_Button;
78     m_Button = NULL;
79 
80     if ( m_PushButton ) delete m_PushButton;
81     m_PushButton = NULL;
82 }
83 
84 
85 //----------------------------------------
86 // 描画
Render()87 void SmButton::Render()
88 {
89     if ( m_IsPressed )
90     {
91         m_PushButton->Render( GL_TRIANGLE_STRIP );
92     }
93 
94     if ( m_OnColor != 0 && m_OffColor != 0 )
95     {
96         m_Button->Render( GL_TRIANGLE_STRIP );
97     }
98 }
99 
100 
101 //----------------------------------------
102 // ボタン状態を設定する
SetSwitch(bool bswitch)103 void SmButton::SetSwitch( bool bswitch )
104 {
105     m_IsSwitch = bswitch;
106 
107     if ( m_IsSwitch )
108     {
109         m_Button->SetVertexColor( m_OnColor );
110     }
111     else
112     {
113         m_Button->SetVertexColor( m_OffColor );
114     }
115 
116     m_Button->Update();
117 }
118 
119 
120 
121 //----------------------------------------
122 // ボタン状態をスワップする
SwapSwitch()123 void SmButton::SwapSwitch()
124 {
125     if ( m_IsSwitch )
126     {
127         m_IsSwitch = false;
128         m_Button->SetVertexColor( m_OffColor );
129     }
130     else
131     {
132         m_IsSwitch = true;
133         m_Button->SetVertexColor( m_OnColor );
134     }
135 
136     m_Button->Update();
137 }
138 
139 
140 //----------------------------------------
141 // ボタンカラーを設定する
SetColor(nw::ut::Color8 onColor,nw::ut::Color8 offColor)142 void SmButton::SetColor( nw::ut::Color8 onColor, nw::ut::Color8 offColor )
143 {
144     m_OnColor = onColor;
145     m_OffColor = offColor;
146 }
147 
148 
149 //----------------------------------------
150 // メッセージ受信
ReceveMessage(SmMessageType type,void * object,uint targetId)151 bool SmButton::ReceveMessage( SmMessageType type, void* object, uint targetId )
152 {
153     NW_UNUSED_VARIABLE(targetId);
154 
155     SmTouchPanelStatus*  touchPanelStaus = NULL;
156 
157     switch( type )
158     {
159     case SM_MESSAGE_TUCHPANEL_PRESS:
160         {
161             touchPanelStaus = static_cast<SmTouchPanelStatus*>(object);
162             NW_NULL_ASSERT( touchPanelStaus );
163 
164             // 他処理で使用中でなければ
165             if ( !touchPanelStaus->IsGrab() )
166             {
167                 // コリジョン内であれば、
168                 if ( m_Collision.CheckInner( touchPanelStaus->GetX(), touchPanelStaus->GetY() ) )
169                 {
170                     // 掴む
171                     touchPanelStaus->Grab();
172                     m_IsGrab    = true;
173                     m_IsPressed = true;
174                 }
175             }
176         }
177         break;
178 
179     case SM_MESSAGE_TUCHPANEL_MOTION:
180         {
181             touchPanelStaus = static_cast<SmTouchPanelStatus*>(object);
182             NW_NULL_ASSERT( touchPanelStaus );
183 
184             m_LastX = touchPanelStaus->GetX();
185             m_LastY = touchPanelStaus->GetY();
186         }
187         break;
188 
189     case SM_MESSAGE_TUCHPANEL_RELEASE:
190         {
191             touchPanelStaus = static_cast<SmTouchPanelStatus*>(object);
192             NW_NULL_ASSERT( touchPanelStaus );
193 
194             // 放す
195             if ( m_IsGrab )
196             {
197                 touchPanelStaus->UnGrab();
198                 m_IsGrab = false;
199                 m_IsPressed = false;
200 
201                 // リリースの際、範囲内であればアップデートをかける
202                 if ( m_Collision.CheckInner( m_LastX, m_LastY ) )
203                 {
204                     // 状態をスワップする
205                     SwapSwitch();
206 
207                     // Updateを送信
208                     if ( m_Target )
209                     {
210                         m_Target->SendMessage( SM_MESSAGE_UPDATE_PARAM, NULL, m_Id );
211                     }
212                 }
213             }
214         }
215         break;
216 
217     default:
218         break;
219     }
220     return 0;
221 }
222 
223 } // namespace
224 
225 
226