1 /******************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  MUI Control Bar
5  * Author:   David Register
6  *
7  ***************************************************************************
8  *   Copyright (C) 2018 by David S. Register                               *
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program; if not, write to the                         *
22  *   Free Software Foundation, Inc.,                                       *
23  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
24  ***************************************************************************
25  *
26  *
27  */
28 
29 #include "wx/wxprec.h"
30 
31 #ifndef  WX_PRECOMP
32 #include "wx/wx.h"
33 #endif //precompiled headers
34 
35 #include <wx/statline.h>
36 
37 #include "dychart.h"
38 
39 #include "chcanv.h"
40 #include "MUIBar.h"
41 #include "OCPNPlatform.h"
42 #include "CanvasOptions.h"
43 #include "styles.h"
44 #include "navutil.h"
45 
46 #ifdef ocpnUSE_SVG
47 #include "wxSVG/svg.h"
48 #endif // ocpnUSE_SVG
49 
50 #ifdef __OCPN__ANDROID__
51 #include "androidUTIL.h"
52 #include "qdebug.h"
53 #endif
54 
55 
56 
57 //------------------------------------------------------------------------------
58 //    External Static Storage
59 //------------------------------------------------------------------------------
60 
61 extern OCPNPlatform              *g_Platform;
62 extern ChartCanvas               *g_focusCanvas;
63 extern ocpnStyle::StyleManager*   g_StyleManager;
64 extern bool                       g_bShowMuiZoomButtons;
65 
66 //  Helper utilities
LoadSVG(const wxString filename,unsigned int width,unsigned int height)67 static wxBitmap LoadSVG( const wxString filename, unsigned int width, unsigned int height )
68 {
69     #ifdef ocpnUSE_SVG
70 #ifdef __OCPN__ANDROID__
71     return loadAndroidSVG( filename, width, height );
72 #else
73     wxSVGDocument svgDoc;
74     if( svgDoc.Load(filename) )
75         return wxBitmap( svgDoc.Render( width, height, NULL, true, true ) );
76     else
77         return wxBitmap(width, height);
78 #endif
79     #else
80         return wxBitmap(width, height);
81     #endif // ocpnUSE_SVG
82 }
83 
84 double getValue(int animationType, double t);
85 
86 
87 //  Helper classes
88 
89 
90 #define ID_SCALE_CANCEL 8301
91 #define ID_SCALE_OK 8302
92 #define ID_SCALECTRL 8303
93 
94 class SetScaleDialog: public wxDialog
95 {
96       DECLARE_EVENT_TABLE()
97 
98       public:
99     /// Constructors
100             SetScaleDialog( );
101             SetScaleDialog( wxWindow* parent, wxWindowID id = SYMBOL_GOTOPOS_IDNAME,
102                                 const wxString& caption = _("Set scale"),
103                                 const wxPoint& pos = wxDefaultPosition,
104                                 const wxSize& size = wxDefaultSize,
105                                 long style = wxDEFAULT_DIALOG_STYLE );
106 
107             ~SetScaleDialog();
108 
109     /// Creation
110             bool Create( wxWindow* parent, wxWindowID id = wxID_ANY,
111                          const wxString& caption = _("Set scale"),
112                          const wxPoint& pos = wxDefaultPosition,
113                          const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
114 
115             void SetColorScheme(ColorScheme cs);
116 
117             void CreateControls();
118 
119             void OnSetScaleCancelClick( wxCommandEvent& event );
120             void OnSetScaleOKClick( wxCommandEvent& event );
121 
122       /// Should we show tooltips?
123 
124             wxTextCtrl*   m_ScaleCtl;
125             wxButton*     m_CancelButton;
126             wxButton*     m_OKButton;
127 
128 };
129 
BEGIN_EVENT_TABLE(SetScaleDialog,wxDialog)130 BEGIN_EVENT_TABLE( SetScaleDialog, wxDialog )
131     EVT_BUTTON( ID_GOTOPOS_CANCEL, SetScaleDialog::OnSetScaleCancelClick )
132     EVT_BUTTON( ID_GOTOPOS_OK, SetScaleDialog::OnSetScaleOKClick )
133 END_EVENT_TABLE()
134 
135 /*!
136  * SetScaleDialog constructors
137  */
138 
139 SetScaleDialog::SetScaleDialog()
140 {
141 }
142 
SetScaleDialog(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)143 SetScaleDialog::SetScaleDialog( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style )
144 {
145     long wstyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT;
146 
147     Create( parent, id, caption, pos, size, wstyle );
148 
149 }
150 
~SetScaleDialog()151 SetScaleDialog::~SetScaleDialog()
152 {
153 }
154 
155 /*!
156  * SetScaleDialog creator
157  */
158 
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)159 bool SetScaleDialog::Create( wxWindow* parent, wxWindowID id, const wxString& caption,
160                                  const wxPoint& pos, const wxSize& size, long style )
161 {
162     SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS );
163     wxDialog::Create( parent, id, caption, pos, size, style );
164 
165     CreateControls();
166     GetSizer()->SetSizeHints( this );
167     Centre();
168 
169     return TRUE;
170 }
171 
172 /*!
173  * Control creation for GoToPositionDialog
174  */
175 
CreateControls()176 void SetScaleDialog::CreateControls()
177 {
178     SetScaleDialog* itemDialog1 = this;
179 
180     wxBoxSizer* itemBoxSizer2 = new wxBoxSizer( wxVERTICAL );
181     itemDialog1->SetSizer( itemBoxSizer2 );
182 
183     wxStaticBox* itemStaticBoxSizer4Static = new wxStaticBox( itemDialog1, wxID_ANY,
184             _("Chart Scale") );
185 
186     wxStaticBoxSizer* itemStaticBoxSizer4 = new wxStaticBoxSizer( itemStaticBoxSizer4Static,
187             wxVERTICAL );
188     itemBoxSizer2->Add( itemStaticBoxSizer4, 0, wxEXPAND | wxALL, 5 );
189 
190     wxStaticText* itemStaticText5 = new wxStaticText( itemDialog1, wxID_STATIC, _(""),
191             wxDefaultPosition, wxDefaultSize, 0 );
192     itemStaticBoxSizer4->Add( itemStaticText5, 0,
193                               wxALIGN_LEFT | wxLEFT | wxRIGHT | wxTOP, 5 );
194 
195     m_ScaleCtl = new wxTextCtrl( itemDialog1, ID_SCALECTRL, _T(""), wxDefaultPosition,  wxSize( 180, -1 ), 0 );
196     itemStaticBoxSizer4->Add( m_ScaleCtl, 0,  wxALIGN_LEFT | wxLEFT | wxRIGHT | wxBOTTOM | wxEXPAND, 5 );
197 
198      wxBoxSizer* itemBoxSizer16 = new wxBoxSizer( wxHORIZONTAL );
199     itemBoxSizer2->Add( itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5 );
200 
201     m_CancelButton = new wxButton( itemDialog1, ID_GOTOPOS_CANCEL, _("Cancel"), wxDefaultPosition,
202                                    wxDefaultSize, 0 );
203     itemBoxSizer16->Add( m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
204 
205     m_OKButton = new wxButton( itemDialog1, ID_GOTOPOS_OK, _("OK"), wxDefaultPosition,
206                                wxDefaultSize, 0 );
207     itemBoxSizer16->Add( m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
208     m_OKButton->SetDefault();
209 
210     SetColorScheme( (ColorScheme) 0 );
211 }
212 
SetColorScheme(ColorScheme cs)213 void SetScaleDialog::SetColorScheme( ColorScheme cs )
214 {
215     DimeControl( this );
216 }
217 
218 
OnSetScaleCancelClick(wxCommandEvent & event)219 void SetScaleDialog::OnSetScaleCancelClick( wxCommandEvent& event )
220 {
221     Close();
222     event.Skip();
223 }
224 
OnSetScaleOKClick(wxCommandEvent & event)225 void SetScaleDialog::OnSetScaleOKClick( wxCommandEvent& event )
226 {
227     SetReturnCode(wxID_OK);
228     EndModal(wxID_OK);
229     return;
230 }
231 
232 
233 
234 //------------------------------------------------------------------------------
235 //    MUIButton Static Storage
236 //------------------------------------------------------------------------------
237 
238 class MUIButton: public wxWindow
239 {
240     DECLARE_DYNAMIC_CLASS( MUIButton )
241     DECLARE_EVENT_TABLE()
242 
243     wxSize DoGetBestSize() const;
244 public:
245     MUIButton();
246     MUIButton(wxWindow* parent, wxWindowID id = wxID_ANY, float scale_factor = 1.0,
247               const wxString & bitmapState0 = wxEmptyString, const wxString & bitmapState1 = wxEmptyString, const wxString & bitmapState2 = wxEmptyString,
248               const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxNO_BORDER);
249 
250     bool Create(wxWindow* parent, wxWindowID id = wxID_ANY, float scale_factor = 1.0,
251                 const wxString & bitmapState0 = wxEmptyString, const wxString & bitmapState1 = wxEmptyString, const wxString & bitmapState2 = wxEmptyString,
252                 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxNO_BORDER);
253 
254     ~MUIButton();
255 
256     void Init();
257     void CreateControls();
258 
259     void SetState( int state);
260 
261     void SetColorScheme( ColorScheme cs );
262     void OnSize( wxSizeEvent& event );
263     void OnPaint( wxPaintEvent& event );
264     void OnLeftDown( wxMouseEvent& event );
265     void OnLeftUp( wxMouseEvent& event );
266 
267 
268     wxBitmap GetBitmapResource( const wxString& name );
269 
270     wxIcon GetIconResource( const wxString& name );
271 
272     /// Should we show tooltips?
273     static bool ShowToolTips();
274 
275 private:
276     wxString m_bitmapFileState0;
277     wxString m_bitmapFileState1;
278     wxString m_bitmapFileState2;
279     wxBitmap m_bitmap;
280     wxBitmap m_bitmapState0;
281     wxBitmap m_bitmapState1;
282     wxBitmap m_bitmapState2;
283 
284     int mState;
285     float m_scaleFactor;
286     wxSize m_styleToolSize;
287     ColorScheme m_cs;
288 };
289 
290 
IMPLEMENT_DYNAMIC_CLASS(MUIButton,wxWindow)291 IMPLEMENT_DYNAMIC_CLASS( MUIButton, wxWindow )
292 
293 
294 
295 BEGIN_EVENT_TABLE( MUIButton, wxWindow )
296 
297 EVT_SIZE( MUIButton::OnSize )
298 EVT_PAINT( MUIButton::OnPaint )
299 EVT_LEFT_DOWN( MUIButton::OnLeftDown )
300 EVT_LEFT_UP( MUIButton::OnLeftUp )
301 
302 END_EVENT_TABLE()
303 
304 
305 MUIButton::MUIButton()
306 {
307     Init();
308 }
309 
MUIButton(wxWindow * parent,wxWindowID id,float scale_factor,const wxString & bitmap,const wxString & bitmapState1,const wxString & bitmapState2,const wxPoint & pos,const wxSize & size,long style)310 MUIButton::MUIButton(wxWindow* parent, wxWindowID id, float scale_factor,
311                      const wxString & bitmap, const wxString & bitmapState1,const wxString & bitmapState2,
312                      const wxPoint& pos, const wxSize& size, long style)
313 {
314     Init();
315     Create(parent, id, scale_factor, bitmap, bitmapState1, bitmapState2, pos, size, style);
316 }
317 
318 
Create(wxWindow * parent,wxWindowID id,float scale_factor,const wxString & bitmap,const wxString & bitmapState1,const wxString & bitmapState2,const wxPoint & pos,const wxSize & size,long style)319 bool MUIButton::Create(wxWindow* parent, wxWindowID id, float scale_factor,
320                        const wxString & bitmap, const wxString & bitmapState1, const wxString & bitmapState2,
321                        const wxPoint& pos, const wxSize& size, long style)
322 {
323     wxWindow::Create(parent, id, pos, size, style);
324     m_bitmapFileState0 = bitmap;
325     m_bitmapFileState1 = bitmapState1;
326     m_bitmapFileState2 = bitmapState2;
327 
328 
329     m_scaleFactor = scale_factor;
330 
331     m_styleToolSize = g_StyleManager->GetCurrentStyle()->GetToolSize();
332 
333     //  Arbitrarily boost the MUIButton default size above the style defined size.  No good reason.....
334     m_styleToolSize = wxSize(m_styleToolSize.x * 1.25, m_styleToolSize.y * 1.25);
335 
336     CreateControls();
337     return true;
338 }
339 
340 
~MUIButton()341 MUIButton::~MUIButton()
342 {
343 }
344 
345 
Init()346 void MUIButton::Init()
347 {
348     mState = 0;
349     m_cs = (ColorScheme)-1; //GLOBAL_COLOR_SCHEME_RGB;
350 }
351 
352 
CreateControls()353 void MUIButton::CreateControls()
354 {
355     this->SetForegroundColour(wxColour(255, 255, 255));
356 
357     wxColour backColor = GetGlobalColor( _T("GREY3"));
358     SetBackgroundColour(backColor);
359 
360     this->SetFont(wxFont(8, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, false, wxT("Tahoma")));
361 }
362 
363 
SetColorScheme(ColorScheme cs)364 void MUIButton::SetColorScheme(ColorScheme cs)
365 {
366     if(m_cs != cs){
367 
368         wxColour backColor = GetGlobalColor( _T("GREY3"));
369         SetBackgroundColour(backColor);
370 
371         ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
372 
373         wxBitmap bmp = LoadSVG( m_bitmapFileState0, GetSize().x, GetSize().y );
374         m_bitmapState0 = style->SetBitmapBrightness(bmp, cs);
375 
376         bmp = LoadSVG( m_bitmapFileState1, GetSize().x, GetSize().y );
377         if(bmp.IsOk())
378             m_bitmapState1 = style->SetBitmapBrightness(bmp, cs);
379         else
380             m_bitmapState1 = m_bitmapState0;
381 
382         bmp = LoadSVG( m_bitmapFileState2, GetSize().x, GetSize().y );
383         if(bmp.IsOk())
384             m_bitmapState2 = style->SetBitmapBrightness(bmp, cs);
385         else
386             m_bitmapState2 = m_bitmapState0;
387 
388 
389         switch(mState){
390             case 0:
391             default:
392                 m_bitmap = m_bitmapState0;
393                 break;
394 
395             case 1:
396                 m_bitmap = m_bitmapState1;
397                 break;
398 
399             case 2:
400                 m_bitmap = m_bitmapState2;
401                 break;
402         }
403 
404         m_cs = cs;
405     }
406 
407 }
408 
409 
ShowToolTips()410 bool MUIButton::ShowToolTips()
411 {
412     return true;
413 }
414 
SetState(int state)415 void MUIButton::SetState( int state)
416 {
417     switch(state){
418             case 0:
419             default:
420                 m_bitmap = m_bitmapState0;
421                 break;
422 
423             case 1:
424                 m_bitmap = m_bitmapState1;
425                 break;
426 
427             case 2:
428                 m_bitmap = m_bitmapState2;
429                 break;
430     }
431 
432     mState = state;
433 
434     Refresh();
435 }
436 
437 
OnSize(wxSizeEvent & event)438 void MUIButton::OnSize( wxSizeEvent& event )
439 {
440     if(m_bitmap.IsOk()){
441         if( event.GetSize() == m_bitmap.GetSize())
442             return;
443     }
444 
445     if(!m_bitmapFileState0.IsEmpty())
446         m_bitmapState0 = LoadSVG( m_bitmapFileState0, event.GetSize().x, event.GetSize().y );
447 
448     if(!m_bitmapFileState1.IsEmpty())
449         m_bitmapState1 = LoadSVG( m_bitmapFileState1, event.GetSize().x, event.GetSize().y );
450     if(!m_bitmapState1.IsOk() || m_bitmapFileState1.IsEmpty())
451         m_bitmapState1 = m_bitmapState0;
452 
453     if(!m_bitmapFileState2.IsEmpty())
454         m_bitmapState2 = LoadSVG( m_bitmapFileState2, event.GetSize().x, event.GetSize().y );
455     if(!m_bitmapState2.IsOk() || m_bitmapFileState2.IsEmpty())
456         m_bitmapState2 = m_bitmapState0;
457 
458     switch(mState){
459         case 0:
460         default:
461             m_bitmap = m_bitmapState0;
462             break;
463 
464         case 1:
465             m_bitmap = m_bitmapState1;
466             break;
467 
468         case 2:
469             m_bitmap = m_bitmapState2;
470             break;
471     }
472 }
473 
GetBitmapResource(const wxString & name)474 wxBitmap MUIButton::GetBitmapResource( const wxString& name )
475 {
476     // Bitmap retrieval
477     wxUnusedVar(name);
478     return wxNullBitmap;
479 }
480 
GetIconResource(const wxString & name)481 wxIcon MUIButton::GetIconResource( const wxString& name )
482 {
483     // Icon retrieval
484     wxUnusedVar(name);
485     return wxNullIcon;
486 }
487 
DoGetBestSize() const488 wxSize MUIButton::DoGetBestSize() const
489 {
490 //     wxSize labelSize = wxDefaultSize;
491 //     GetTextExtent(m_Label, &labelSize.x, &labelSize.y);
492 //     return wxSize(wxMax(40, labelSize.x + 20), wxMax(20, labelSize.y + 10));
493     return wxSize(m_styleToolSize.x * m_scaleFactor, m_styleToolSize.y * m_scaleFactor);
494 }
495 
496 
OnPaint(wxPaintEvent & event)497 void MUIButton::OnPaint( wxPaintEvent& event )
498 {
499     wxPaintDC dc( this );
500 
501     if(m_bitmap.IsOk()){
502         dc.DrawBitmap(m_bitmap, 0, 0, true);
503     }
504 
505 
506 #if 0
507     wxBufferedPaintDC dc(this);
508 
509     wxRect clientRect = GetClientRect();
510     wxRect gradientRect = clientRect;
511     gradientRect.SetHeight(gradientRect.GetHeight()/2 + ((GetCapture() == this) ? 1 : 0));
512     if(GetCapture() != this)
513     {
514         dc.GradientFillLinear(gradientRect,
515                               m_GradientTopStartColour, m_GradientTopEndColour, wxSOUTH);
516     }
517     else
518     {
519         dc.SetPen(wxPen(m_PressedColourTop));
520         dc.SetBrush(wxBrush(m_PressedColourTop));
521         dc.DrawRectangle(gradientRect);
522     }
523 
524     gradientRect.Offset(0, gradientRect.GetHeight());
525 
526     if(GetCapture() != this)
527     {
528         dc.GradientFillLinear(gradientRect,
529                               m_GradientBottomStartColour, m_GradientBottomEndColour, wxSOUTH);
530     }
531     else
532     {
533         dc.SetPen(wxPen(m_PressedColourBottom));
534         dc.SetBrush(wxBrush(m_PressedColourBottom));
535         dc.DrawRectangle(gradientRect);
536     }
537     dc.SetPen(wxPen(GetBackgroundColour()));
538     dc.SetBrush(*wxTRANSPARENT_BRUSH);
539     dc.DrawRectangle(0, 0, clientRect.GetWidth(), clientRect.GetHeight());
540     dc.SetFont(GetFont());
541     dc.SetTextForeground(GetForegroundColour());
542     if(GetCapture() == this)
543     {
544         clientRect.Offset(1, 1);
545     }
546     dc.DrawLabel(m_Label, clientRect, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL);
547 #endif
548 }
549 
550 
551 #if 1
OnLeftDown(wxMouseEvent & event)552 void MUIButton::OnLeftDown( wxMouseEvent& event )
553 {
554     event.Skip();
555 }
556 
557 
OnLeftUp(wxMouseEvent & event)558 void MUIButton::OnLeftUp( wxMouseEvent& event )
559 {
560     if(GetClientRect().Contains(event.GetPosition())){
561         wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, GetId());
562         GetParent()->GetEventHandler()->AddPendingEvent( evt );
563     }
564     event.Skip();
565 }
566 #endif
567 
568 
569 
570 
571 
572 
573 #define CANVAS_OPTIONS_ANIMATION_TIMER_1 800
574 #define CANVAS_OPTIONS_TIMER 801
575 
576 //------------------------------------------------------------------------------
577 //          MUIBar Window Implementation
578 //------------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MUIBar,wxFrame)579 BEGIN_EVENT_TABLE(MUIBar, wxFrame)
580 EVT_TIMER ( CANVAS_OPTIONS_ANIMATION_TIMER_1, MUIBar::onCanvasOptionsAnimationTimerEvent )
581 //EVT_PAINT ( MUIBar::OnPaint )
582 EVT_SIZE( MUIBar::OnSize )
583 EVT_MENU(-1, MUIBar::OnToolLeftClick)
584 EVT_TIMER(CANVAS_OPTIONS_TIMER, MUIBar::CaptureCanvasOptionsBitmapChain)
585 
586 END_EVENT_TABLE()
587 
588 // Define a constructor
589 MUIBar::MUIBar()
590 {
591 }
592 
MUIBar(ChartCanvas * parent,int orientation,float size_factor,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)593 MUIBar::MUIBar(ChartCanvas* parent, int orientation, float size_factor, wxWindowID id, const wxPoint& pos, const wxSize& size, long style,  const wxString& name)
594 {
595     m_parentCanvas = parent;
596     m_orientation = orientation;
597 
598     //SetBackgroundStyle( wxBG_STYLE_TRANSPARENT );
599     //wxWindow::Create(parent, id, pos, size, style, name);
600     //long mstyle = wxSIMPLE_BORDER;
601     long mstyle = wxNO_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_SHAPED | wxFRAME_FLOAT_ON_PARENT;
602 
603     m_scaleFactor = size_factor;
604     m_cs = (ColorScheme)-1;
605 
606     wxFrame::Create(parent, id, _T(""), pos, size, mstyle, name);
607     Init();
608     CreateControls();
609     //Show();
610 }
611 
612 
613 
614 
~MUIBar()615 MUIBar::~MUIBar()
616 {
617     if(m_canvasOptions){
618         m_canvasOptions->Destroy();
619         m_canvasOptions = 0;
620     }
621     if(m_scaleTextBox)
622         m_scaleTextBox->Unbind(wxEVT_LEFT_DOWN, &MUIBar::OnScaleSelected, this);
623 
624 }
625 
Init()626 void MUIBar::Init()
627 {
628     m_zinButton = NULL;
629     m_zoutButton = NULL;
630     m_followButton = NULL;
631     m_menuButton = NULL;
632 
633     m_canvasOptions = NULL;
634     m_canvasOptionsAnimationTimer.SetOwner(this, CANVAS_OPTIONS_ANIMATION_TIMER_1);
635     m_backcolorString = _T("GREY3");
636     m_scaleTextBox = NULL;
637     m_capture_size_y = 0;
638 
639     m_COTopOffset = 60;  //  TODO should be below GPS/Compass
640 
641     CanvasOptionTimer.SetOwner( this, CANVAS_OPTIONS_TIMER );
642     m_coAnimateByBitmaps = false;
643     m_bEffects = true;
644 #ifdef __OCPN__ANDROID__
645     m_bEffects =false;
646 #endif
647 
648 }
649 
SetColorScheme(ColorScheme cs)650 void MUIBar::SetColorScheme( ColorScheme cs )
651 {
652     if( m_cs != cs ){
653         wxColour backColor = GetGlobalColor( m_backcolorString );
654         SetBackgroundColour(backColor);
655 
656         if(m_zinButton)
657             m_zinButton->SetColorScheme(cs);
658         if(m_zoutButton)
659             m_zoutButton->SetColorScheme(cs);
660         if(m_followButton)
661             m_followButton->SetColorScheme(cs);
662         if(m_menuButton)
663             m_menuButton->SetColorScheme(cs);
664 
665         if(m_scaleTextBox){
666             wxColour textbackColor = GetGlobalColor( _T("GREY1") );
667             m_scaleTextBox->SetForegroundColour(textbackColor);
668         }
669         Refresh();
670         m_cs = cs;
671     }
672 }
673 
OnScaleSelected(wxMouseEvent & event)674 void MUIBar::OnScaleSelected( wxMouseEvent &event )
675 {
676     ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
677         if(!pcc) return;
678 
679     SetScaleDialog dlg(pcc);
680     dlg.Centre();
681     dlg.ShowModal();
682     if( dlg.GetReturnCode() == wxID_OK ) {
683         wxString newScale = dlg.m_ScaleCtl->GetValue();
684         if(newScale.Contains(':'))
685             newScale = newScale.AfterFirst(':');
686         double dScale;
687         if(newScale.ToDouble(&dScale)){
688             // Try to constrain the scale to something reasonable
689             dScale = wxMin(dScale, 3e6);
690             dScale = wxMax(dScale, 1000);
691             double displayScaleNow = pcc->GetScaleValue();
692             double factor = displayScaleNow / dScale;
693             pcc->DoZoomCanvas( factor );
694 
695             // Run the calculation again, to reduce roundoff error in large scale jumps.
696             displayScaleNow = pcc->GetScaleValue();
697             factor = displayScaleNow / dScale;
698             pcc->DoZoomCanvas( factor );
699 
700         }
701     }
702 }
703 
SetCanvasENCAvailable(bool avail)704 void MUIBar::SetCanvasENCAvailable(bool avail)
705 {
706     m_CanvasENCAvail = avail;
707     if(m_canvasOptions)
708         m_canvasOptions->SetENCAvailable( avail );
709 }
710 
711 
CreateControls()712 void MUIBar::CreateControls()
713 {
714     //SetBackgroundStyle( wxBG_STYLE_TRANSPARENT );
715 
716     wxColour backColor = GetGlobalColor( m_backcolorString );
717     SetBackgroundColour(backColor);
718     wxBoxSizer *topSizer;
719 
720     wxString iconDir = g_Platform->GetSharedDataDir() + _T("uidata/MUI_flat/");
721 
722     if(m_orientation == wxHORIZONTAL){
723         topSizer = new wxBoxSizer(wxVERTICAL);
724         SetSizer(topSizer);
725 
726         wxBoxSizer *barSizer = new wxBoxSizer(wxHORIZONTAL);
727         topSizer->Add(barSizer, 0, wxEXPAND );
728 
729         // Buttons
730 
731         if(g_bShowMuiZoomButtons){
732         m_zinButton = new MUIButton( this, ID_ZOOMIN, m_scaleFactor, iconDir + _T("MUI_zoom-in.svg"));
733         barSizer->Add(m_zinButton, 0, wxSHAPED);
734 
735         m_zoutButton = new MUIButton( this, ID_ZOOMOUT, m_scaleFactor, iconDir + _T("MUI_zoom-out.svg"));
736         barSizer->Add(m_zoutButton, 0, wxSHAPED);
737 
738         barSizer->AddSpacer(2);
739         }
740 
741 #ifndef __OCPN__ANDROID__
742         //  Scale
743         m_scaleTextBox = new wxStaticText(this, wxID_ANY, _("1:400000"));
744         wxColour textbackColor = GetGlobalColor( _T("GREY1") );
745         m_scaleTextBox->SetForegroundColour(textbackColor);
746         barSizer->Add(m_scaleTextBox, 0, wxALIGN_CENTER_VERTICAL );
747         m_scaleTextBox->Bind(wxEVT_LEFT_DOWN, &MUIBar::OnScaleSelected, this);
748 
749         barSizer->AddSpacer(5);
750 
751         m_followButton = new MUIButton( this, ID_FOLLOW, m_scaleFactor,
752                                         iconDir + _T("MUI_follow.svg"), iconDir + _T("MUI_follow_active.svg"), iconDir + _T("MUI_follow_ahead.svg"));
753         barSizer->Add(m_followButton, 0, wxSHAPED);
754 
755         barSizer->AddSpacer(2);
756 #endif
757         m_menuButton = new MUIButton( this, ID_MUI_MENU, m_scaleFactor, iconDir + _T("MUI_menu.svg"));
758         barSizer->Add(m_menuButton, 0,  wxSHAPED);
759     }
760     else{
761         topSizer = new wxBoxSizer(wxVERTICAL);
762         SetSizer(topSizer);
763 
764         wxBoxSizer *barSizer = new wxBoxSizer(wxVERTICAL);
765         topSizer->Add(barSizer, 0, wxEXPAND );
766 
767         // Buttons
768         if(g_bShowMuiZoomButtons){
769         m_zinButton = new MUIButton( this, ID_ZOOMIN, m_scaleFactor, iconDir + _T("MUI_zoom-in.svg"));
770         barSizer->Add(m_zinButton, 1, wxSHAPED);
771 
772         m_zoutButton = new MUIButton( this, ID_ZOOMOUT, m_scaleFactor, iconDir + _T("MUI_zoom-out.svg"));
773         barSizer->Add(m_zoutButton, 1, wxSHAPED);
774 
775         barSizer->AddSpacer(5);
776         }
777 
778 #ifndef __OCPN__ANDROID__
779         m_followButton = new MUIButton( this, ID_FOLLOW, m_scaleFactor,
780                                         iconDir + _T("MUI_follow.svg"), iconDir + _T("MUI_follow_active.svg"), iconDir + _T("MUI_follow_ahead.svg"));
781         barSizer->Add(m_followButton, 1, wxSHAPED);
782 
783         barSizer->AddSpacer(5);
784 #endif
785 
786         m_menuButton = new MUIButton( this, ID_MUI_MENU, m_scaleFactor, iconDir + _T("MUI_menu.svg"));
787         barSizer->Add(m_menuButton, 1,  wxALIGN_RIGHT | wxSHAPED);
788 
789 
790     }
791 
792 
793     //topSizer->SetSizeHints( this );
794     topSizer->Fit( this );
795 
796 
797 }
798 
SetBestPosition(void)799 void MUIBar::SetBestPosition( void )
800 {
801 #if 0 // for wxWindow
802     int x = (m_parent->GetClientSize().x - GetSize().x) / 2;
803     if(x > 0){
804         int bottomOffset = 0;
805 
806         ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
807         bottomOffset += pcc->GetPianoHeight();
808 
809         int y = m_parent->GetClientSize().y - GetSize().y - bottomOffset;
810         SetSize(x, y, -1, -1, wxSIZE_USE_EXISTING);
811     }
812 
813 #else   // for wxDialog
814     int x = (m_parent->GetClientSize().x - (GetSize().x * 1.00));
815 
816 #ifndef __WXGTK__       // Adjust for wxNO_BORDER canvas window style
817     x -= 2;
818 #endif
819 
820     //if(x > 0)
821     {
822         int bottomOffset = 2;
823 
824         ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
825 //         bottomOffset += pcc->GetPianoHeight();
826 
827         int y = m_parent->GetClientSize().y - GetSize().y - bottomOffset;
828 
829         wxPoint m_position = wxPoint(x,y);
830         wxPoint screenPos = pcc->ClientToScreen( m_position );
831 
832         //  GTK sometimes has trouble with ClientToScreen() if executed in the context of an event handler
833         //  The position of the window is calculated incorrectly if a deferred Move() has not been processed yet.
834         //  So work around this here...
835 
836 #ifdef __WXGTK__
837         wxPoint pp = m_parent->GetPosition();
838         wxPoint ppg = m_parent->GetParent()->GetScreenPosition();
839         wxPoint screen_pos_fix = ppg + pp + m_position;
840         screenPos.x = screen_pos_fix.x;
841 #endif
842 
843         Move( screenPos );
844 
845         if(m_canvasOptions){
846             m_canvasOptions->Destroy();
847             m_canvasOptions = 0;
848         }
849         Show();
850 
851     }
852 #endif
853 }
854 
OnSize(wxSizeEvent & event)855 void MUIBar::OnSize( wxSizeEvent& event )
856 {
857     //int buttonSize = event.GetSize().y / 2;
858     Layout();
859 
860 #if !defined(__WXMAC__) && !defined(__OCPN__ANDROID__)
861     if(1) {
862         wxBitmap m_MaskBmp = wxBitmap( GetSize().x, GetSize().y );
863         wxMemoryDC sdc( m_MaskBmp );
864         sdc.SetBackground( *wxWHITE_BRUSH );
865         sdc.Clear();
866         sdc.SetBrush( *wxBLACK_BRUSH );
867         sdc.SetPen( *wxBLACK_PEN );
868         sdc.DrawRoundedRectangle( 0, 0, m_MaskBmp.GetWidth(), m_MaskBmp.GetHeight(), 5 );
869         sdc.SelectObject( wxNullBitmap );
870         SetShape( wxRegion( m_MaskBmp, *wxWHITE, 0 ) );
871     }
872 #endif
873 
874 }
875 
UpdateDynamicValues()876 void MUIBar::UpdateDynamicValues()
877 {
878     if(!m_scaleTextBox)
879         return;
880 
881     wxString scaleString;
882     int scale = m_parentCanvas->GetScaleValue();
883     if(scale < 1e6)
884         scaleString.Printf(_T("1:%d"), scale);
885     else
886         scaleString.Printf(_T("1:%4.1f MM"), scale / 1e6);
887 
888     if(m_scaleTextBox)
889     m_scaleTextBox->SetLabel(scaleString);
890 }
891 
SetFollowButtonState(int state)892 void MUIBar::SetFollowButtonState( int state )
893 {
894     if(m_followButton)
895     m_followButton->SetState( state );
896 }
897 
OnToolLeftClick(wxCommandEvent & event)898 void MUIBar::OnToolLeftClick(  wxCommandEvent& event )
899 {
900     //  Handle the MUIButton clicks here
901     ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
902 
903     switch( event.GetId() ){
904 
905         case ID_ZOOMIN:
906         case ID_ZOOMOUT:
907         {
908             wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, event.GetId());
909             GetParent()->GetEventHandler()->AddPendingEvent( evt );
910 
911              if(g_focusCanvas)
912                  g_focusCanvas->TriggerDeferredFocus();
913             break;
914         }
915 
916         case ID_FOLLOW:
917         {
918             wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, event.GetId());
919             GetParent()->GetEventHandler()->AddPendingEvent( evt );
920 
921             if(g_focusCanvas)
922                 g_focusCanvas->TriggerDeferredFocus();
923             break;
924         }
925 
926         case ID_MUI_MENU:
927         {
928             if(!m_canvasOptions){
929                 m_canvasOptions = new CanvasOptions(m_parent);
930 
931                 // calculate best size for CanvasOptions dialog
932 
933                 wxPoint parentClientUpperRight = m_parent->ClientToScreen(wxPoint( m_parent->GetSize().x, 0));
934                 wxRect rmui = m_parentCanvas->GetMUIBarRect();
935                 int size_y = rmui.y - (parentClientUpperRight.y + m_COTopOffset);
936                 size_y -= GetCharHeight();
937                 size_y = wxMax(size_y, 100);            // ensure always big enough to see
938 
939                 m_canvasOptions->SetSize(wxSize(-1, size_y));
940                 m_canvasOptionsFullSize = m_canvasOptions->GetSize();
941                 m_canvasOptionsFullSize.x += m_canvasOptions->GetCharWidth();  // Allow for scroll bar, since sizer won't do it.
942 
943                 if(1)
944                     m_currentCOPos = m_parent->ClientToScreen(wxPoint( m_parent->GetSize().x, m_COTopOffset));
945                 else
946                     m_currentCOPos = wxPoint( m_parent->GetSize().x, 20);
947 
948                 m_canvasOptions->Move(m_currentCOPos);
949                 m_canvasOptions->Hide();
950             }
951 
952             m_canvasOptions->SetENCAvailable(m_CanvasENCAvail);
953 
954             if(m_canvasOptions->IsShown())
955                 PushCanvasOptions();            // hide it
956             else{
957                 // Grab the backing bitmap, if available
958 
959                 if(m_coAnimateByBitmaps && m_capture_size_y){
960                     int overShoot_x = m_canvasOptions->GetSize().x * 2 / 10;    //20%
961                     m_backingPoint = wxPoint(m_capturePoint.x - overShoot_x, m_capturePoint.y);
962 
963                     m_backingBitmap = wxBitmap(m_canvasOptionsFullSize.x  + overShoot_x, m_capture_size_y, -1);
964                     wxMemoryDC mdcb;
965                     mdcb.SelectObject(m_backingBitmap);
966                     wxScreenDC sdc;
967                     mdcb.Blit(0, 0, m_canvasOptionsFullSize.x  + overShoot_x, m_capture_size_y, &sdc, m_capturePoint.x - overShoot_x, m_capturePoint.y, wxCOPY);
968                     mdcb.SelectObject(wxNullBitmap);
969                 }
970                 PullCanvasOptions();
971             }
972 
973             break;
974         }
975 
976         default:
977             break;
978     }
979     //event.Skip();
980 }
981 
CaptureCanvasOptionsBitmap()982 void MUIBar::CaptureCanvasOptionsBitmap()
983 {
984     m_coSequence = 0;
985     CanvasOptionTimer.Start(100, wxTIMER_ONE_SHOT );
986 }
987 
988 
989 
CaptureCanvasOptionsBitmapChain(wxTimerEvent & event)990 void MUIBar::CaptureCanvasOptionsBitmapChain( wxTimerEvent& event )
991 {
992     if(m_coSequence == 0){
993 
994 
995         if(!m_canvasOptions)
996             m_canvasOptions = new CanvasOptions(m_parent);
997 
998         wxPoint parentClientUpperRight = m_parent->ClientToScreen(wxPoint( m_parent->GetSize().x, 0));
999         wxRect rmui = m_parentCanvas->GetMUIBarRect();
1000         int size_y = rmui.y - (parentClientUpperRight.y + m_COTopOffset);
1001         size_y -= GetCharHeight();
1002         size_y = wxMax(size_y, 100);            // ensure always big enough to see
1003         m_capture_size_y = size_y;
1004 
1005         m_canvasOptions->SetSize(wxSize(-1, size_y));
1006 
1007         m_capturePoint = m_parent->ClientToScreen(wxPoint( m_parent->GetSize().x, m_COTopOffset));
1008         m_canvasOptions->Move(m_capturePoint);
1009         m_canvasOptions->Show();
1010 
1011         m_coSequence++;
1012         CanvasOptionTimer.Start(1, wxTIMER_ONE_SHOT );
1013     }
1014 
1015     else if(m_coSequence == 1){
1016         m_capturePoint = m_parent->ClientToScreen(wxPoint( m_parent->GetSize().x - m_canvasOptionsFullSize.x, m_COTopOffset));
1017         m_canvasOptions->Move(m_capturePoint);
1018 
1019         m_coSequence++;
1020         CanvasOptionTimer.Start(1, wxTIMER_ONE_SHOT );
1021     }
1022 
1023     else if(m_coSequence == 2){
1024         m_animateBitmap = wxBitmap(m_canvasOptions->GetSize().x, m_capture_size_y, -1);
1025         wxMemoryDC mdc(m_animateBitmap);
1026 
1027         wxScreenDC sdc;
1028 
1029         mdc.Blit(0, 0, m_canvasOptions->GetSize().x, m_capture_size_y, &sdc, m_capturePoint.x, m_capturePoint.y, wxCOPY);
1030         mdc.SelectObject(wxNullBitmap);
1031 
1032         //delete m_canvasOptions;
1033         //m_canvasOptions = NULL;
1034     }
1035 
1036 }
1037 
1038 
1039 
1040 
OnEraseBackground(wxEraseEvent & event)1041 void MUIBar::OnEraseBackground( wxEraseEvent& event )
1042 {
1043 }
1044 
1045 
OnPaint(wxPaintEvent & event)1046 void MUIBar::OnPaint( wxPaintEvent& event )
1047 {
1048     return;
1049 
1050     int width, height;
1051     GetClientSize( &width, &height );
1052     wxPaintDC dc( this );
1053 
1054 //    dc.SetBackgroundMode(wxTRANSPARENT);
1055 //    dc.SetBackground(*wxTRANSPARENT_BRUSH);
1056 
1057 //     dc.SetPen( *wxTRANSPARENT_PEN );
1058 //     dc.SetBrush( *wxTRANSPARENT_BRUSH );
1059 //     dc.DrawRectangle( 0, 0, width, height);
1060 
1061     wxColour backColor = GetGlobalColor( m_backcolorString );
1062 
1063 
1064     dc.SetBrush( wxBrush( backColor/*wxColour(200, 200, 200)*/) );
1065     dc.SetPen( wxPen( backColor) );
1066     dc.DrawRoundedRectangle( 0, 0, width - 10, height - 10, 8 );
1067 }
1068 
ResetCanvasOptions()1069 void MUIBar::ResetCanvasOptions()
1070 {
1071     delete m_canvasOptions;
1072     m_canvasOptions = NULL;
1073 }
1074 
PullCanvasOptions()1075 void MUIBar::PullCanvasOptions()
1076 {
1077     //  Target position
1078     int cox = m_parent->GetSize().x - m_canvasOptionsFullSize.x;
1079     int coy = m_COTopOffset;
1080         m_targetCOPos = m_parent->ClientToScreen(wxPoint(cox, coy));
1081 
1082     if(!m_bEffects){
1083         m_canvasOptions->Move(m_targetCOPos);
1084         m_canvasOptions->Show();
1085         return;
1086     }
1087 
1088     //  Capture the animation bitmap, if required..
1089 
1090     if(m_coAnimateByBitmaps && !m_animateBitmap.IsOk() ){
1091         m_canvasOptions->Move(m_targetCOPos);
1092         m_canvasOptions->Show();
1093         CaptureCanvasOptionsBitmap();
1094         return;
1095     }
1096 
1097 
1098 
1099     //  Setup animation parameters
1100     //  Start Position
1101     m_startCOPos = m_canvasOptions->GetPosition();
1102 
1103     //  Present Position
1104     m_currentCOPos = m_startCOPos;
1105 
1106     m_animationType = CO_ANIMATION_CUBIC_REVERSE; //CO_ANIMATION_CUBIC_BACK_IN;
1107     m_animateSteps = 10;
1108     m_animationTotalTime = 200;  // msec
1109 
1110     m_pushPull = CO_PULL;
1111     ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
1112     pcc->m_b_paint_enable = false;
1113 
1114     // Start the animation....
1115     m_animateStep = 0;
1116     m_canvasOptionsAnimationTimer.Start(10, true);
1117     m_canvasOptions->Move(m_targetCOPos);
1118     m_canvasOptions->Hide();
1119 
1120 }
1121 
1122 
1123 
PushCanvasOptions()1124 void MUIBar::PushCanvasOptions()
1125 {
1126     if(!m_bEffects){
1127         m_canvasOptions->Hide();
1128         return;
1129     }
1130 
1131     //  Setup animation parameters
1132 
1133     //  Target position
1134     int cox = m_parent->GetSize().x;
1135     int coy = 20;
1136 
1137     if(1)
1138         m_targetCOPos = m_parent->ClientToScreen(wxPoint(cox, coy));
1139     else
1140         m_targetCOPos = wxPoint(cox, coy);
1141 
1142     //  Start Position
1143     m_startCOPos = m_canvasOptions->GetPosition();
1144 
1145     //  Present Position
1146     m_currentCOPos = m_startCOPos;
1147 
1148     //  Animation type
1149     m_animationType = CO_ANIMATION_LINEAR;
1150     m_animateSteps = 5;
1151     m_animationTotalTime = 100;  // msec
1152     m_pushPull = CO_PUSH;
1153     ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
1154 
1155     // Start the animation....
1156     m_animateStep = 0;
1157     m_canvasOptionsAnimationTimer.Start(10, true);
1158     m_canvasOptions->Show();
1159 
1160 }
1161 
onCanvasOptionsAnimationTimerEvent(wxTimerEvent & event)1162 void MUIBar::onCanvasOptionsAnimationTimerEvent( wxTimerEvent &event )
1163 {
1164     double progress = m_animateStep / (double) m_animateSteps;
1165     double valueX = getValue(m_animationType, progress);
1166 
1167     double dx = (m_targetCOPos.x - m_startCOPos.x) * valueX;
1168 
1169     wxPoint newPos = wxPoint(m_startCOPos.x + dx, m_currentCOPos.y);
1170 
1171     int size_x;
1172     if(m_pushPull == CO_PULL)
1173         size_x =  abs(dx);
1174     else
1175         size_x = (m_targetCOPos.x - m_startCOPos.x) - abs(dx);
1176 
1177     if(!m_coAnimateByBitmaps){
1178         m_canvasOptions->SetSize(newPos.x, newPos.y, size_x, wxDefaultCoord, wxSIZE_USE_EXISTING);
1179         //m_canvasOptions->GetSizer()->Layout();
1180         m_canvasOptions->Show();
1181     }
1182     else{
1183         m_canvasOptions->Hide();
1184         wxScreenDC sdc;
1185 
1186          if(1/*m_pushPull == CO_PULL*/){
1187             //  restore Backing bitmap, to cover any overshoot
1188             if(m_backingBitmap.IsOk()){
1189                 wxMemoryDC mdc_back(m_backingBitmap);
1190                 sdc.Blit(m_backingPoint.x, m_backingPoint.y, m_backingBitmap.GetWidth() - size_x, m_backingBitmap.GetHeight(), &mdc_back, 0, 0, wxCOPY);
1191             }
1192         }
1193 
1194          wxMemoryDC mdc(m_animateBitmap);
1195          sdc.Blit(newPos.x, newPos.y, size_x, m_animateBitmap.GetHeight(), &mdc, 0, 0, wxCOPY);
1196          mdc.SelectObject(wxNullBitmap);
1197 
1198     }
1199 
1200     m_currentCOPos = newPos;
1201 
1202     double dt = m_animationTotalTime / m_animateSteps;
1203 
1204     if(m_animateStep++ < m_animateSteps + 1){
1205         m_canvasOptionsAnimationTimer.Start(dt, true);
1206     }
1207     else{
1208         m_currentCOPos = m_targetCOPos;
1209         m_canvasOptions->Show(m_pushPull == CO_PULL);
1210 
1211         ChartCanvas *pcc = wxDynamicCast(m_parent, ChartCanvas);
1212         if(pcc){
1213             pcc->m_b_paint_enable = true;
1214 
1215             if(m_pushPull == CO_PUSH){
1216                 delete m_canvasOptions;
1217                 m_canvasOptions = NULL;
1218             }
1219 #ifdef __WXOSX__
1220             if(m_pushPull == CO_PUSH)
1221                 pcc->TriggerDeferredFocus();
1222 #else
1223             pcc->TriggerDeferredFocus();
1224 #endif
1225 
1226             pcc->Refresh();
1227         }
1228 
1229     }
1230 
1231 }
1232 
1233 //   Animation support
1234 
bounceMaker(double t,double c,double a)1235 double bounceMaker(double t, double c, double a)
1236 {
1237     if (t == 1.0) return c;
1238     if (t < (4/11.0)) {
1239         return c*(7.5625*t*t);
1240     } else if (t < (8/11.0)) {
1241         t -= (6/11.0);
1242         return -a * (1. - (7.5625*t*t + .75)) + c;
1243     } else if (t < (10/11.0)) {
1244         t -= (9/11.0);
1245         return -a * (1. - (7.5625*t*t + .9375)) + c;
1246     } else {
1247         t -= (21/22.0);
1248         return -a * (1. - (7.5625*t*t + .984375)) + c;
1249     }
1250 }
1251 
getValue(int animationType,double t)1252 double getValue(int animationType, double t)
1253 {
1254     double value = 0;
1255     double s = 1;
1256     double tp;
1257     switch (animationType){
1258         case CO_ANIMATION_LINEAR:
1259         default:
1260             value = t;
1261             break;
1262         case CO_ANIMATION_CUBIC:
1263             tp = t - 1.0;
1264             value = tp*tp*tp + 1;
1265             //value = t*t*t;
1266             break;
1267         case CO_ANIMATION_CUBIC_REVERSE:
1268             tp = t - 1.0;
1269             value = tp*tp*tp + 1;
1270             break;
1271         case CO_ANIMATION_CUBIC_BOUNCE_IN:
1272             value = bounceMaker(t, 1, s);
1273             break;
1274 
1275         case CO_ANIMATION_CUBIC_BACK_IN:
1276             tp = t - 1.0;
1277             value = tp*tp*((s+1)*tp+ s) + 1;
1278             break;
1279 
1280     }
1281 
1282     return value;
1283 }
1284