fix compile against newer giflib
[rofl0r-obeditor.git] / src / levels__Panel_StageView.cpp
blobb4e206e618bba562c08a61afe0a494b7c9666f77
1 #include "wx/wxprec.h"
2 #ifndef WX_PRECOMP
3 #include "wx/wx.h"
4 #endif
6 #include <wx/dcmemory.h>
7 #include <wx/dcbuffer.h>
9 #include "common__mod.h"
10 #include "common__ob_controls.h"
11 #include "common__object_stage.h"
12 #include "images__MyPalette.h"
14 #include "ob_editor.h"
15 #include "levels__globals.h"
16 #include "levels__classes.h"
17 #include "levels__sidesWindows.h"
18 #include "levels__CtrlStageView.h"
19 #include "levels__Panel_StageView.h"
20 #include "levels__Ob_GObjects.h"
21 #include "levels__ObImgs_Manager.h"
23 using namespace std;
25 //-------------------------------------------------------
26 extern LevelEditorFrame *leFrame;
27 //-------------------------------------------------------
28 float MAP_ZF = 0.5;
29 size_t SCENE_MAP_HEIGHT= 150;
31 //-------------------------------------------------------
32 wxBitmap*
33 Build_All_Panels_Img( ob_stage_panel** oPanels,
34 size_t oPanels__size,
35 wxColour& background_color,
36 bool b_transparent
39 if( oPanels__size == 0 )
40 return new wxBitmap(*noImg);
42 //-------------------------------------------------
43 // Compute panels_size
44 wxSize panels_size(0,0);
45 wxSize min_size(6000,6000);
46 size_t nb_invalids = 0;
48 for( size_t i = 0; i < oPanels__size; i++)
50 ob_stage_panel* curr = oPanels[i];
51 if( curr == NULL )
53 nb_invalids++;
54 continue;
57 wxString imgPath = curr->GetFileName().GetFullPath();
58 wxImage theImg( imgPath );
59 if( theImg.IsOk() == false )
61 nb_invalids++;
62 continue;
65 // total w
66 panels_size.x += theImg.GetWidth();
67 // total H
68 if( theImg.GetHeight() > panels_size.y )
69 panels_size.y = theImg.GetHeight();
70 // Min Size
71 if( theImg.GetWidth() < min_size.x )
72 min_size.x = theImg.GetWidth();
73 if( theImg.GetHeight() < min_size.y )
74 min_size.y = theImg.GetHeight();
76 panels_size.x += nb_invalids * min_size.x;
78 //-----------------------------------
79 // Build Invalid Panel Image
80 wxImage* img_invalid_panel = NULL;
81 if( nb_invalids > 0 )
83 img_invalid_panel = new wxImage(*noImg);
84 // Only invalid Panels !!
85 if( nb_invalids == oPanels__size )
87 panels_size = wxSize( 240, 300 );
88 img_invalid_panel->Rescale( 240, 300 );
90 else
91 img_invalid_panel->Rescale( min_size.x, min_size.y );
95 //-----------------------------------
96 // Init the dc and Bitmap
97 wxMemoryDC dc;
98 wxBitmap* theBitmap = new wxBitmap(panels_size.x,panels_size.y);
99 dc.SelectObject( *theBitmap );
100 dc.SetBackground(background_color);
101 dc.Clear();
103 //-----------------------------------
104 // Draw the panels in the Bitmap
105 int curr_x = 0;
106 for( size_t i = 0; i < oPanels__size; i++)
108 ob_stage_panel* curr = oPanels[i];
109 bool b_invalid = false;
110 if( curr == NULL )
111 b_invalid = true;
113 wxImage* theImg = NULL;
114 if(b_invalid == false )
116 wxString imgPath = curr->GetFileName().GetFullPath();
117 theImg = new wxImage( imgPath );
118 if( theImg == NULL || theImg->IsOk() == false )
120 b_invalid = true;
121 if( theImg != NULL )
122 delete theImg;
126 if( b_invalid == true )
127 theImg = img_invalid_panel;
129 wxBitmap t_bmp(*theImg);
130 dc.DrawBitmap( t_bmp, curr_x, 0, b_transparent);
131 curr_x += theImg->GetWidth();
132 if( b_invalid == false )
133 delete theImg;
136 if( img_invalid_panel != NULL )
137 delete img_invalid_panel;
138 dc.SelectObject( wxNullBitmap );
139 return theBitmap;
143 //*****************************************************************
144 //*****************************************************************
145 //*****************************************************************
146 //*****************************************************************
147 //-------------------------------------------------------
148 Panel_StageView::Panel_StageView(wxWindow* _parent )
149 :wxPanel( _parent, wxID_ANY )
151 wxBoxSizer *sizer_main = new wxBoxSizer( wxVERTICAL );
153 obImgs_Mgr = new ObImgs_Manager();
154 coords_to_restore = wxSize(-100000,-100000);
155 f_hidden = 0;
157 wxWindow* t_btn;
158 // MyPaletteElementCtrl* colourChooser;
160 //--------------------------------
161 // TOOLS
162 wxBoxSizer *sizer_tools = new wxBoxSizer( wxHORIZONTAL );
163 sizer_main->Add( sizer_tools, 0, wxEXPAND );
165 t_btn = new wxBitmapButton( this, wxID_ANY
166 ,wxBitmap(wxImage(GetRessourceFile_String(wxT("zoom-out.png"))) ));
167 t_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED
168 , wxCommandEventHandler(Panel_StageView::Evt_ZoomM)
169 , NULL, this);
170 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
172 t_btn = new wxBitmapButton( this, wxID_ANY
173 ,wxBitmap(wxImage(GetRessourceFile_String(wxT("zoom-x1.png"))) ));
174 t_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED
175 , wxCommandEventHandler(Panel_StageView::Evt_ZoomReset)
176 , NULL, this);
177 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
179 t_btn = new wxBitmapButton( this, wxID_ANY
180 ,wxBitmap(wxImage(GetRessourceFile_String(wxT("zoom-in.png"))) ));
181 t_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED
182 , wxCommandEventHandler(Panel_StageView::Evt_ZoomP)
183 , NULL, this);
184 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
188 sizer_tools->AddSpacer( 5 );
189 t_btn = new wxStaticText( this, wxID_ANY, wxT("BG : ") );
190 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
192 bgColourChooser = new MyPaletteElementCtrl( this, AUTO_ELTCOLOR );
193 bgColourChooser->Connect( wxPALETTE_ELT_COLOR_CHANGE
194 , wxCommandEventHandler(Panel_StageView::Evt_BG_ColourChange)
195 , NULL, this);
196 sizer_tools->Add( bgColourChooser, 0, wxALL|wxCENTER, 3 );
198 t_btn = new wxCheckBox( this, wxID_ANY, wxT("Hide") );
199 t_btn->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED
200 , wxCommandEventHandler(Panel_StageView::Evt_BG_VisibleChange)
201 , NULL, this);
202 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
206 sizer_tools->AddSpacer( 5 );
208 t_btn = new wxBitmapButton( this, wxID_ANY
209 ,wxBitmap(wxImage(GetRessourceFile_String(wxT("delete-small.png"))) ));
210 t_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED
211 , wxCommandEventHandler(Panel_StageView::Evt_DeleteObjects)
212 , NULL, this);
213 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
215 t_btn = new wxBitmapButton( this, wxID_ANY
216 ,wxBitmap(wxImage(GetRessourceFile_String(wxT("copy-small.png"))) ));
217 t_btn->Connect( wxEVT_COMMAND_BUTTON_CLICKED
218 , wxCommandEventHandler(Panel_StageView::Evt_DuplicateObjects)
219 , NULL, this);
220 sizer_tools->Add( t_btn, 0, wxALL|wxCENTER, 3 );
223 //--------------------------------
224 // VIEW CTRL
225 stageMap = NULL;
226 stageView = new StageView( this );
227 sizer_main->Add( stageView, 1, wxEXPAND );
229 //--------------------------------
230 // MAP CTRL
231 stageMap = new StageMap( this );
232 stageMap->SetMinSize( wxSize(wxDefaultCoord, SCENE_MAP_HEIGHT) );
233 stageMap->SetSize( wxSize(wxDefaultCoord, SCENE_MAP_HEIGHT) );
234 sizer_main->Add( stageMap, 0, wxEXPAND|wxTOP|wxBOTTOM| wxFIXED_MINSIZE, 6 );
235 stageMap->m_flag |= stageMap->M_SM_INIT;
237 //--------------------------------
238 // FINALLY
239 bgColourChooser->SetColor( stageView->background_color );
240 SetSizer( sizer_main );
243 //-------------------------------------------------------
244 Panel_StageView::~Panel_StageView()
246 Reset();
248 // Free the Panels Images Manager
249 ObImgs_Manager* t = obImgs_Mgr;
250 obImgs_Mgr = NULL;
251 delete t;
255 //-------------------------------------------------------
256 void
257 Panel_StageView::UpdateView()
259 OBJECTS__Refresh();
262 //-------------------------------------------------------
263 void
264 Panel_StageView::Refresh(bool eraseBackground, const wxRect* rect)
266 wxPanel::Refresh(eraseBackground, rect);
267 // stageMap->Refresh(eraseBackground, rect);
270 //-------------------------------------------------------
271 void
272 Panel_StageView::SaveState()
274 ConfigEdit_Write(wxT("Panel_StageView/zoom_factor")
275 , FloatToStr(stageView->zoom_factor ));
276 ConfigEdit_Write(wxT("Panel_StageView/coords_x")
277 , IntToStr(stageView->coords.x ));
278 ConfigEdit_Write(wxT("Panel_StageView/coords_y")
279 , IntToStr(stageView->coords.y ));
281 ConfigEdit_Write(wxT("Panel_StageView/BG_color"), wxColour_ToStr( stageView->background_color) );
284 //-------------------------------------------------------
285 void
286 Panel_StageView::LoadState()
288 wxString s;
289 s = ConfigEdit_Read(wxT("Panel_StageView/zoom_factor"));
290 if( s != wxString() )
291 stageView->zoom_factor = StrToFloat( s );
292 s = ConfigEdit_Read(wxT("Panel_StageView/coords_x") );
293 if( s != wxString() )
294 coords_to_restore.x = StrToInt( s );
295 s = ConfigEdit_Read(wxT("Panel_StageView/coords_y") );
296 if( s != wxString() )
297 coords_to_restore.y = StrToInt( s );
299 s = ConfigEdit_Read(wxT("Panel_StageView/BG_color") );
300 if( s != wxString() )
302 stageView->background_color = wxColour_FromStr(s);
303 bgColourChooser->SetColor(stageView->background_color );
306 UpdateView();
309 //-------------------------------------------------------
310 void
311 Panel_StageView::Reset()
313 obImgs_Mgr->Reset();
314 stageView->Reset();
315 stageMap->Reset();
318 //-------------------------------------------------------
319 void
320 Panel_StageView::Reload__ALL()
322 obImgs_Mgr->Reset();
323 PANELS__Reload();
324 OBJECTS__Reload();
327 //-------------------------------------------------------
328 void
329 Panel_StageView::PANELS__Reload()
331 obImgs_Mgr->Reset();
332 stageView->Reload_Panels();
333 stageMap->Reload_Panels();
334 stageView->Refresh();
337 //-------------------------------------------------------
338 void
339 Panel_StageView::OBJECTS__Reload()
341 obImgs_Mgr->Reset();
342 stageView->Reset_Ob_GObjects();
343 OBJECTS__Refresh();
347 //-------------------------------------------------------
348 void
349 Panel_StageView::OBJECTS__Refresh()
351 stageView->Refresh();
352 stageMap->Refresh();
355 //-------------------------------------------------------
356 void
357 Panel_StageView::Delete_GuiObject_of( ob_stage_object* o )
359 stageView->Delete_GuiObject_of( o );
362 //-------------------------------------------------------
363 void
364 Panel_StageView::Evt_ZoomP( wxCommandEvent& evt )
366 stageView->ZoomP();
369 //-------------------------------------------------------
370 void
371 Panel_StageView::Evt_ZoomM( wxCommandEvent& evt )
373 stageView->ZoomM();
376 //-------------------------------------------------------
377 void
378 Panel_StageView::Evt_ZoomReset( wxCommandEvent& evt )
380 stageView->ZoomSet( 1 );
383 //-------------------------------------------------------
384 void
385 Panel_StageView::Evt_BG_ColourChange( wxCommandEvent& evt )
387 stageView->background_color = bgColourChooser->GetColor();
388 OBJECTS__Refresh();
391 //-------------------------------------------------------
392 void
393 Panel_StageView::Evt_BG_VisibleChange( wxCommandEvent& evt )
395 if( f_hidden & FM_BACKGROUND )
396 f_hidden &= ~FM_BACKGROUND;
397 else
398 f_hidden |= FM_BACKGROUND;
399 OBJECTS__Refresh();
402 //-------------------------------------------------------
403 void
404 Panel_StageView::Evt_DeleteObjects( wxCommandEvent& evt )
406 leFrame->OBJECT__ListSelected__Delete();
409 //-------------------------------------------------------
410 void
411 Panel_StageView::Evt_DuplicateObjects( wxCommandEvent& evt )
413 leFrame->OBJECT__ListSelected__Duplicate();
416 //-------------------------------------------------------
417 void
418 Panel_StageView::EvtMouse( wxMouseEvent& evt )
420 evt.Skip();
423 //-------------------------------------------------------
424 BEGIN_EVENT_TABLE(Panel_StageView, wxPanel)
425 EVT_MOUSE_EVENTS( Panel_StageView::EvtMouse )
426 END_EVENT_TABLE()
428 //*****************************************************************
429 //*****************************************************************
430 //*****************************************************************
431 //*****************************************************************
432 //-------------------------------------------------------
433 StageMap::StageMap(Panel_StageView* _parent )
434 :wxControl(_parent,wxID_ANY, wxDefaultPosition,wxDefaultSize,
435 wxBORDER_SIMPLE | wxHSCROLL | wxVSCROLL
438 b_must_reload_panels = true;
439 m_flag = 0;
440 psv = _parent;
441 panelBitmap = NULL;
442 coords = wxSize(0,0);
443 b_refreshing = false;
445 color_view_borders = wxColour( 0,255,0);
446 SetBackgroundStyle( wxBG_STYLE_CUSTOM );
447 SetBackgroundColour( *wxWHITE );
448 SCROLLBARS_Update();
451 //-------------------------------------------------------
452 StageMap::~StageMap()
454 if( panelBitmap != NULL )
455 delete panelBitmap;
456 panelBitmap = NULL;
459 //-------------------------------------------------------
460 void
461 StageMap::Reload_Panels()
463 b_must_reload_panels = false;
464 if( panelBitmap != NULL )
465 delete panelBitmap;
466 panelBitmap = NULL;
468 if( curr_stageFile == NULL || curr_stageFile->obj_container == NULL )
469 return;
471 ob_stage* theStage = (ob_stage*) curr_stageFile->obj_container;
472 size_t oPanels__size;
473 ob_stage_panel** oPanels = theStage->Get_Panels( oPanels__size);
474 if( oPanels == NULL )
475 return;
477 panelBitmap =
478 Build_All_Panels_Img( oPanels,
479 oPanels__size,
480 psv->stageView->background_color,
481 false
483 delete[] oPanels;
485 // Some image transformation
486 wxImage t_img( panelBitmap->ConvertToImage() );
487 t_img.Rescale( t_img.GetWidth() * MAP_ZF
488 , t_img.GetHeight() * MAP_ZF );
489 delete panelBitmap;
490 unsigned char* pixs = t_img.GetData();
491 size_t nb_pixels_elts = t_img.GetWidth() * t_img.GetHeight() * 3;
492 for( size_t i = 0; i<nb_pixels_elts; i+=3 )
494 wxImage::RGBValue _rgb(pixs[i],pixs[i+1],pixs[i+2]);
495 wxImage::HSVValue hsv = t_img.RGBtoHSV(_rgb );
496 hsv.saturation /= 3;
497 hsv.value /= 2;
498 _rgb = t_img.HSVtoRGB( hsv);
499 pixs[i] = _rgb.red;
500 pixs[i+1] = _rgb.green;
501 pixs[i+2] = _rgb.blue;
504 panelBitmap = new wxBitmap( t_img );
507 //-------------------------------------------------------
508 void
509 StageMap::SCROLLBARS_Update()
511 if( panelBitmap == NULL )
513 coords = wxSize(0,0);
514 SetScrollbar( wxHORIZONTAL,0,0,0 );
515 SetScrollbar( wxVERTICAL, 0,0,0 );
516 return;
519 wxSize c(GetClientSize());
520 c.x /= MAP_ZF;
521 c.y /= MAP_ZF;
522 wxSize max_size(psv->coords_max.x - psv->coords_min.x
523 ,psv->coords_max.y - psv->coords_min.y );
525 if( max_size.x <= c.x )
527 SetScrollbar( wxHORIZONTAL,0,0,0 );
528 coords.x = (max_size.x - c.x)/2 + psv->coords_min.x;
529 Refresh();
531 else
532 SetScrollbar( wxHORIZONTAL, coords.x - psv->coords_min.x
533 , c.x, max_size.x );
535 if( max_size.y <= c.y )
537 SetScrollbar( wxVERTICAL,0,0,0 );
538 coords.y = (max_size.y - c.y)/2+ psv->coords_min.y;
539 Refresh();
541 else
542 SetScrollbar( wxVERTICAL, coords.y - psv->coords_min.y
543 , c.y, max_size.y );
547 //-------------------------------------------------------
548 void
549 StageMap::Reset()
553 //-------------------------------------------------------
554 void
555 StageMap::EvtSize( wxSizeEvent& evt )
557 evt.Skip();
558 SCROLLBARS_Update();
559 if( m_flag & M_SM_INIT )
560 SCENE_MAP_HEIGHT = GetClientSize().GetHeight();
561 Refresh();
564 //-------------------------------------------------------
565 void
566 StageMap::EvtScroll( wxScrollWinEvent& evt )
568 if( evt.GetOrientation() == wxHORIZONTAL )
570 SetScrollPos( wxHORIZONTAL, evt.GetPosition() );
571 coords.x = GetScrollPos( wxHORIZONTAL ) + psv->coords_min.x;
573 else //GetOrientation() == wxVERTICAL
575 SetScrollPos( wxVERTICAL, evt.GetPosition() );
576 coords.y = GetScrollPos( wxVERTICAL ) + psv->coords_min.y;
579 Refresh();
582 //-------------------------------------------------------
583 void
584 StageMap::Refresh(bool eraseBackground, const wxRect* rect)
586 if( b_refreshing == true )
587 return;
589 b_refreshing = true;
590 wxControl::Refresh( eraseBackground,rect );
591 // GetParent()->Refresh(eraseBackground,rect);
592 b_refreshing = false;
595 //-------------------------------------------------------
596 void
597 StageMap::EvtMouse( wxMouseEvent& evt )
599 wxSize mCoords(evt.m_x/MAP_ZF,evt.m_y/MAP_ZF);
600 wxSize viewSize(psv->stageView->Get_ObSize());
601 mCoords.x += coords.x - viewSize.x/2;
602 mCoords.y += coords.y - viewSize.y/2;
603 if(
604 (evt.Dragging() == true && evt.m_leftDown == true )
606 evt.LeftDown() == true
610 psv->stageView->SetViewCoords( mCoords );
613 if( evt.GetWheelRotation() != 0 )
615 int i = evt.GetWheelRotation() / evt.m_wheelDelta ;
616 if( i > 0 )
617 psv->stageView->ZoomP(i);
618 else
619 psv->stageView->ZoomM(-i);
620 psv->stageView->SetViewCoords( mCoords );
621 return;
625 //-------------------------------------------------------
626 void
627 StageMap::EvtPaint( wxPaintEvent& _evt )
629 wxBufferedPaintDC dc(this);
630 wxSize client_size = GetClientSize();
632 if( panelBitmap == NULL && b_must_reload_panels )
633 Reload_Panels();
635 //---------------------------------------------------------
636 // Clear the background
637 dc.SetBackground(psv->stageView->background_color);
638 dc.Clear();
640 // If Invalid panel img objects
641 if( panelBitmap == NULL )
643 wxString img_txt = wxT("No Valid Panels !");
644 dc.SetBackground( *wxWHITE_BRUSH);
645 dc.SetPen( *wxBLACK_PEN );
646 dc.SetFont(
647 wxFont( 20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, true )
649 dc.DrawText( img_txt, client_size.x/3, client_size.y * 2 / 5);
652 //---------------------------------------------------------
653 // Draw the panels
654 else
655 dc.DrawBitmap( *panelBitmap
656 , wxPoint(-coords.x*MAP_ZF, -coords.y*MAP_ZF)
657 , false );
659 // translation of coords to ob_coords
660 wxSize c(coords);
661 #define T_X( X ) (X-c.x)*MAP_ZF
662 #define T_Y( Y ) (Y-c.y)*MAP_ZF
664 //---------------------------------------------------------
665 // Draw the objects
666 list<Ob_GAtom*>::iterator it(psv->stageView->l_atoms.begin())
667 , it_end(psv->stageView->l_atoms.end());
668 for(; it != it_end; it++ )
670 Ob_GAtom* o = *it;
671 if( o == NULL || o->id_atom == GATOM_SHADOW )
672 continue;
673 wxSize o_coords( o->coords );
674 if( o->id_atom == GATOM_CURSOR || o->id_atom == GATOM_AT )
675 o_coords.y = coords.y;
677 if( o->bitmap_Mini != NULL )
678 dc.DrawBitmap( *o->bitmap_Mini
679 , wxPoint( T_X( o_coords.x ), T_Y( o_coords.y ))
680 , true
684 //---------------------------------------------------------
685 // Draw also the current Stage view boundaries
686 dc.SetPen( wxPen(color_view_borders));
687 dc.SetBrush( *wxTRANSPARENT_BRUSH );
689 wxSize sv_c(psv->stageView->coords);
690 wxSize sv_s(psv->stageView->Get_ObSize());
691 dc.DrawRectangle( T_X( sv_c.x )
692 , T_Y( sv_c.y )
693 , sv_s.x*MAP_ZF
694 , sv_s.y*MAP_ZF
700 //-------------------------------------------------------
701 //-------------------------------------------------------
702 BEGIN_EVENT_TABLE(StageMap, wxControl)
703 EVT_SIZE( StageMap::EvtSize )
704 EVT_PAINT( StageMap::EvtPaint )
705 EVT_SCROLLWIN( StageMap::EvtScroll )
706 EVT_MOUSE_EVENTS( StageMap::EvtMouse )
707 END_EVENT_TABLE()