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