~ubuntu-branches/ubuntu/hardy/codeblocks/hardy-backports

« back to all changes in this revision

Viewing changes to src/plugins/contrib/wxSmith/wxwidgets/wxsitemeditorcontent.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Casadevall
  • Date: 2008-07-17 04:39:23 UTC
  • Revision ID: james.westby@ubuntu.com-20080717043923-gmsy5cwkdjswghkm
Tags: upstream-8.02
ImportĀ upstreamĀ versionĀ 8.02

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* This file is part of wxSmith plugin for Code::Blocks Studio
 
3
* Copyright (C) 2006-2007  Bartlomiej Swiecki
 
4
*
 
5
* wxSmith is free software; you can redistribute it and/or modify
 
6
* it under the terms of the GNU General Public License as published by
 
7
* the Free Software Foundation; either version 3 of the License, or
 
8
* (at your option) any later version.
 
9
*
 
10
* wxSmith is distributed in the hope that it will be useful,
 
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
13
* GNU General Public License for more details.
 
14
*
 
15
* You should have received a copy of the GNU General Public License
 
16
* along with wxSmith. If not, see <http://www.gnu.org/licenses/>.
 
17
*
 
18
* $Revision: 4850 $
 
19
* $Id: wxsitemeditorcontent.cpp 4850 2008-01-29 21:45:49Z byo $
 
20
* $HeadURL: svn://svn.berlios.de/codeblocks/tags/8.02/src/plugins/contrib/wxSmith/wxwidgets/wxsitemeditorcontent.cpp $
 
21
*/
 
22
 
 
23
#include "wxsitemeditorcontent.h"
 
24
#include "wxsitemeditordragassist.h"
 
25
#include "wxsbaseproperties.h"
 
26
#include "wxsitemresdata.h"
 
27
#include "wxsiteminfo.h"
 
28
#include "wxsparent.h"
 
29
#include "wxsitemeditor.h"
 
30
#include "wxsgridpanel.h"
 
31
#include "../wxscoder.h"
 
32
#include <wx/app.h>
 
33
 
 
34
BEGIN_EVENT_TABLE(wxsItemEditorContent,wxsDrawingWindow)
 
35
    EVT_MOUSE_EVENTS(wxsItemEditorContent::OnMouse)
 
36
    EVT_KEY_DOWN(wxsItemEditorContent::OnKeyDown)
 
37
END_EVENT_TABLE()
 
38
 
 
39
wxsItemEditorContent::wxsItemEditorContent(wxWindow* Parent,wxsItemResData* Data,wxsItemEditor* Editor):
 
40
    wxsDrawingWindow(Parent,-1,wxDefaultPosition,wxDefaultSize,wxHSCROLL|wxVSCROLL|wxWANTS_CHARS),
 
41
    m_Data(Data),
 
42
    m_Editor(Editor),
 
43
    m_RebuildMaps(false),
 
44
    m_MouseState(msIdle),
 
45
    m_CurDragPoint(0),
 
46
    m_CurDragItem(0),
 
47
    m_Assist(0),
 
48
    m_AssistTarget(0),
 
49
    m_AssistParent(0),
 
50
    m_AssistAddAfter(false),
 
51
    m_TargetInfo(0)
 
52
{
 
53
    m_Assist = new wxsItemEditorDragAssist(this);
 
54
}
 
55
 
 
56
wxsItemEditorContent::~wxsItemEditorContent()
 
57
{
 
58
    ClearDragPoints();
 
59
    delete m_Assist;
 
60
    wxsCoder::Get()->Flush(0);
 
61
}
 
62
 
 
63
void wxsItemEditorContent::PaintExtra(wxDC* DC)
 
64
{
 
65
    m_Assist->DrawExtra(m_AssistTarget,m_AssistParent,m_AssistAddAfter,DC);
 
66
 
 
67
    for ( size_t i = m_DragPoints.Count(); i-- > 0; )
 
68
    {
 
69
        DragPointData* DPD = m_DragPoints[i];
 
70
        if ( DPD->Grey )
 
71
        {
 
72
            DC->SetPen(*wxGREY_PEN);
 
73
            DC->SetBrush(*wxGREY_BRUSH);
 
74
        }
 
75
        else
 
76
        {
 
77
            DC->SetPen(*wxBLACK_PEN);
 
78
            DC->SetBrush(*wxBLACK_BRUSH);
 
79
        }
 
80
        int PosX = DPD->PosX - m_DragBoxSize/2;
 
81
        int PosY = DPD->PosY - m_DragBoxSize/2;
 
82
        DC->DrawRectangle(PosX , PosY, m_DragBoxSize, m_DragBoxSize );
 
83
    }
 
84
 
 
85
    if ( m_MouseState==msTargetSearch && m_TargetInfo )
 
86
    {
 
87
        DC->DrawBitmap(m_TargetInfo->Icon16,m_TargetX+16,m_TargetY,true);
 
88
    }
 
89
}
 
90
 
 
91
void wxsItemEditorContent::RefreshSelection()
 
92
{
 
93
    RebuildDragPoints();
 
94
    FastRepaint();
 
95
}
 
96
 
 
97
void wxsItemEditorContent::ClearDragPoints()
 
98
{
 
99
    for ( size_t i = m_DragPoints.Count(); i-- > 0; )
 
100
    {
 
101
        delete m_DragPoints[i];
 
102
    }
 
103
    m_DragPoints.Clear();
 
104
}
 
105
 
 
106
void wxsItemEditorContent::GreyDragPoints()
 
107
{
 
108
    for ( size_t i = m_DragPoints.Count(); i-->0; )
 
109
    {
 
110
        m_DragPoints[i]->Grey = true;
 
111
    }
 
112
}
 
113
 
 
114
void wxsItemEditorContent::RebuildDragPoints()
 
115
{
 
116
    ClearDragPoints();
 
117
    AddDragPoints(m_Data->GetRootItem(),m_Data->GetLastSelection());
 
118
}
 
119
 
 
120
void wxsItemEditorContent::AddDragPoints(wxsItem* Item,wxsItem* RootSelection)
 
121
{
 
122
    if ( Item->GetIsSelected() )
 
123
    {
 
124
        int PosX, PosY;
 
125
        int SizeX, SizeY;
 
126
        if ( FindAbsoluteRect(Item,PosX,PosY,SizeX,SizeY) )
 
127
        {
 
128
            bool Grey = Item!=RootSelection;
 
129
            DragPointData* ItemPoints[DragBoxTypeCnt];
 
130
 
 
131
            for ( int i=0; i<DragBoxTypeCnt; ++i )
 
132
            {
 
133
                ItemPoints[i] = new DragPointData;
 
134
                ItemPoints[i]->Grey = Grey;
 
135
                ItemPoints[i]->PosX = PosX;
 
136
                ItemPoints[i]->PosY = PosY;
 
137
                ItemPoints[i]->Item = Item;
 
138
                ItemPoints[i]->Type = (DragBoxType)i;
 
139
 
 
140
                if ( i == Top || i == Btm )
 
141
                {
 
142
                    ItemPoints[i]->PosX += SizeX / 2;
 
143
                }
 
144
                else if ( i == RightTop || i == Right || i == RightBtm )
 
145
                {
 
146
                    ItemPoints[i]->PosX += SizeX;
 
147
                }
 
148
 
 
149
                if ( i==Left || i == Right )
 
150
                {
 
151
                    ItemPoints[i]->PosY += SizeY / 2;
 
152
                }
 
153
                else if ( i == LeftBtm || i == Btm || i == RightBtm )
 
154
                {
 
155
                    ItemPoints[i]->PosY += SizeY;
 
156
                }
 
157
 
 
158
                ItemPoints[i]->DragInitPosX = ItemPoints[i]->PosX;
 
159
                ItemPoints[i]->DragInitPosY = ItemPoints[i]->PosY;
 
160
            }
 
161
 
 
162
            for ( int i=0; i<DragBoxTypeCnt; ++i )
 
163
            {
 
164
                memcpy(ItemPoints[i]->ItemPoints,ItemPoints,sizeof(ItemPoints[0]->ItemPoints));
 
165
                m_DragPoints.Add(ItemPoints[i]);
 
166
            }
 
167
        }
 
168
    }
 
169
 
 
170
    wxsParent* Parent = Item->ConvertToParent();
 
171
    if ( Parent )
 
172
    {
 
173
        for ( int i = Parent->GetChildCount(); i-->0; )
 
174
        {
 
175
            AddDragPoints(Parent->GetChild(i),RootSelection);
 
176
        }
 
177
    }
 
178
}
 
179
 
 
180
void wxsItemEditorContent::UpdateDragPoints(DragPointData* anyPoint)
 
181
{
 
182
    DragPointData** ItemPoints = anyPoint->ItemPoints;
 
183
    wxsItem* Item = anyPoint->Item;
 
184
 
 
185
    int PosX, PosY;
 
186
    int SizeX, SizeY;
 
187
    if ( FindAbsoluteRect(Item,PosX,PosY,SizeX,SizeY) )
 
188
    {
 
189
        for ( int i=0; i<DragBoxTypeCnt; ++i )
 
190
        {
 
191
            ItemPoints[i]->PosX = PosX;
 
192
            ItemPoints[i]->PosY = PosY;
 
193
            ItemPoints[i]->Item = Item;
 
194
 
 
195
            if ( i == Top || i == Btm )
 
196
            {
 
197
                ItemPoints[i]->PosX += SizeX / 2;
 
198
            }
 
199
            else if ( i == RightTop || i == Right || i == RightBtm )
 
200
            {
 
201
                ItemPoints[i]->PosX += SizeX;
 
202
            }
 
203
 
 
204
            if ( i==Left || i == Right )
 
205
            {
 
206
                ItemPoints[i]->PosY += SizeY / 2;
 
207
            }
 
208
            else if ( i == LeftBtm || i == Btm || i == RightBtm )
 
209
            {
 
210
                ItemPoints[i]->PosY += SizeY;
 
211
            }
 
212
 
 
213
            ItemPoints[i]->DragInitPosX = ItemPoints[i]->PosX;
 
214
            ItemPoints[i]->DragInitPosY = ItemPoints[i]->PosY;
 
215
        }
 
216
    }
 
217
}
 
218
 
 
219
bool wxsItemEditorContent::FindAbsoluteRect(wxsItem* Item,int& PosX,int& PosY,int& SizeX,int& SizeY)
 
220
{
 
221
    if ( !Item ) return false;
 
222
    ItemToRectT::iterator i = m_ItemToRect.find(Item);
 
223
    if ( i==m_ItemToRect.end() ) return false;
 
224
    wxRect& Rect = (*i).second;
 
225
    PosX = Rect.GetX();
 
226
    PosY = Rect.GetY();
 
227
    SizeX = Rect.GetWidth();
 
228
    SizeY = Rect.GetHeight();
 
229
    return true;
 
230
}
 
231
 
 
232
wxsItem* wxsItemEditorContent::FindItemAtPos(int PosX,int PosY,wxsItem* SearchIn)
 
233
{
 
234
    int itemPosX;
 
235
    int itemPosY;
 
236
    int itemSizeX;
 
237
    int itemSizeY;
 
238
 
 
239
    if ( !FindAbsoluteRect(SearchIn,itemPosX,itemPosY,itemSizeX,itemSizeY) ) return 0;
 
240
 
 
241
    if ( PosX < itemPosX ) return 0;
 
242
    if ( PosX >= (itemPosX+itemSizeX) ) return 0;
 
243
    if ( PosY < itemPosY ) return 0;
 
244
    if ( PosY >= (itemPosY+itemSizeY) ) return 0;
 
245
 
 
246
    wxsParent* parent = SearchIn->ConvertToParent();
 
247
    if ( parent )
 
248
    {
 
249
        for ( int i = parent->GetChildCount(); i-->0; )
 
250
        {
 
251
            wxsItem* f = FindItemAtPos(PosX,PosY,parent->GetChild(i));
 
252
            if ( f )
 
253
            {
 
254
                return f;
 
255
            }
 
256
        }
 
257
    }
 
258
 
 
259
    return SearchIn;
 
260
}
 
261
 
 
262
wxsItemEditorContent::DragPointData* wxsItemEditorContent::FindDragPointAtPos(int PosX,int PosY)
 
263
{
 
264
    for ( size_t i=m_DragPoints.Count(); i-->0; )
 
265
    {
 
266
        DragPointData* DPD = m_DragPoints[i];
 
267
        int dpx = DPD->PosX - (m_DragBoxSize/2);
 
268
        int dpy = DPD->PosY - (m_DragBoxSize/2);
 
269
 
 
270
        if ( (PosX >= dpx) && (PosX < dpx+m_DragBoxSize) &&
 
271
             (PosY >= dpy) && (PosY < dpy+m_DragBoxSize) )
 
272
        {
 
273
            return DPD;
 
274
        }
 
275
    }
 
276
 
 
277
// TODO (SpOoN#1#): Search for edges
 
278
 
 
279
    return 0;
 
280
}
 
281
 
 
282
wxsItemEditorContent::DragPointData* wxsItemEditorContent::FindDragPointFromItem(wxsItem* Item)
 
283
{
 
284
    for ( size_t i = 0; i<m_DragPoints.Count(); i+= 8 )
 
285
    {
 
286
        if ( m_DragPoints[i]->Item == Item )
 
287
        {
 
288
            return m_DragPoints[i];
 
289
        }
 
290
    }
 
291
    return 0;
 
292
}
 
293
 
 
294
void wxsItemEditorContent::OnMouse(wxMouseEvent& event)
 
295
{
 
296
    // Anti-recursion lock
 
297
    static bool IsRunning = false;
 
298
    if ( IsRunning ) return;
 
299
    IsRunning = true;
 
300
 
 
301
    if ( event.ButtonDown() )
 
302
    {
 
303
        SetFocus();
 
304
    }
 
305
    else if ( m_MouseState == msWaitForIdle )
 
306
    {
 
307
        m_MouseState = msIdle;
 
308
    }
 
309
 
 
310
    int NewX = event.m_x;
 
311
    int NewY = event.m_y;
 
312
    CalcUnscrolledPosition(NewX,NewY,&NewX,&NewY);
 
313
    event.m_x = NewX;
 
314
    event.m_y = NewY;
 
315
    switch ( m_MouseState )
 
316
    {
 
317
        case msDraggingPointInit: OnMouseDraggingPointInit (event); break;
 
318
        case msDraggingPoint:     OnMouseDraggingPoint     (event); break;
 
319
        case msDraggingItemInit:  OnMouseDraggingItemInit  (event); break;
 
320
        case msDraggingItem:      OnMouseDraggingItem      (event); break;
 
321
        case msTargetSearch:      OnMouseTargetSearch      (event); break;
 
322
        case msWaitForIdle:                                         break;
 
323
        default:                  OnMouseIdle              (event); break;
 
324
    }
 
325
 
 
326
    IsRunning = false;
 
327
}
 
328
 
 
329
void wxsItemEditorContent::OnMouseIdle(wxMouseEvent& event)
 
330
{
 
331
    BlockFetch(false);
 
332
    m_DragInitPosX = event.GetX();
 
333
    m_DragInitPosY = event.GetY();
 
334
 
 
335
    int MouseX = event.GetX();
 
336
    int MouseY = event.GetY();
 
337
 
 
338
    wxsItem* OnCursor = FindItemAtPos(MouseX,MouseY,m_Data->GetRootItem());
 
339
    if ( !OnCursor ) OnCursor = m_Data->GetRootItem();
 
340
 
 
341
    wxWindow* Preview = GetPreviewWindow(OnCursor);
 
342
 
 
343
    if ( event.LeftDClick() && !event.RightIsDown() && !event.MiddleIsDown() )
 
344
    {
 
345
        if ( Preview )
 
346
        {
 
347
            int PosX, PosY, SizeX, SizeY;
 
348
            FindAbsoluteRect(OnCursor,PosX,PosY,SizeX,SizeY);
 
349
            if ( OnCursor->MouseDClick(Preview,MouseX-PosX,MouseY-PosY) )
 
350
            {
 
351
                m_MouseState = msWaitForIdle;
 
352
                m_Editor->RebuildPreview();
 
353
                m_MouseState = msWaitForIdle;
 
354
                return;
 
355
            }
 
356
        }
 
357
    }
 
358
 
 
359
    if ( event.LeftDown() && !event.LeftDClick() && !event.RightIsDown() && !event.MiddleIsDown() )
 
360
    {
 
361
        // Selecting / drag init event
 
362
        bool NeedRefresh = false;
 
363
        if ( Preview )
 
364
        {
 
365
            int PosX, PosY, SizeX, SizeY;
 
366
            FindAbsoluteRect(OnCursor,PosX,PosY,SizeX,SizeY);
 
367
            NeedRefresh = OnCursor->MouseClick(Preview,MouseX-PosX,MouseY-PosY);
 
368
        }
 
369
 
 
370
        if ( NeedRefresh )
 
371
        {
 
372
            m_MouseState = msWaitForIdle;
 
373
            m_Editor->RebuildPreview();
 
374
            m_MouseState = msWaitForIdle;
 
375
            return;
 
376
        }
 
377
 
 
378
        DragPointData* DPD = FindDragPointAtPos(MouseX,MouseY);
 
379
 
 
380
        if ( DPD )
 
381
        {
 
382
            // If there's drag point, starting point-dragging sequence
 
383
            m_CurDragPoint = DPD;
 
384
            m_CurDragItem = DPD->Item;
 
385
            m_MouseState = msDraggingPointInit;
 
386
        }
 
387
        else
 
388
        {
 
389
            if ( !OnCursor->GetIsSelected() )
 
390
            {
 
391
                m_Data->SelectItem(OnCursor,!event.ControlDown());
 
392
            }
 
393
            else
 
394
            {
 
395
                m_Data->SelectItem(OnCursor,false);
 
396
            }
 
397
 
 
398
            m_CurDragPoint = FindDragPointFromItem(OnCursor);
 
399
            m_CurDragItem = OnCursor;
 
400
            m_MouseState = msDraggingItemInit;
 
401
 
 
402
            if ( !m_CurDragPoint || !m_CurDragItem )
 
403
            {
 
404
                // If we're here, preview has probably not been updated yet
 
405
                m_MouseState = msWaitForIdle;
 
406
            }
 
407
        }
 
408
    }
 
409
 
 
410
    if ( !event.LeftIsDown() && event.RightDown() && !event.MiddleIsDown() )
 
411
    {
 
412
        if ( Preview )
 
413
        {
 
414
            int PosX, PosY, SizeX, SizeY;
 
415
            FindAbsoluteRect(OnCursor,PosX,PosY,SizeX,SizeY);
 
416
            if ( OnCursor->MouseRightClick(Preview,MouseX-PosX,MouseY-PosY) )
 
417
            {
 
418
                m_MouseState = msWaitForIdle;
 
419
                m_Editor->RebuildPreview();
 
420
                m_MouseState = msWaitForIdle;
 
421
                return;
 
422
            }
 
423
        }
 
424
    }
 
425
 
 
426
    if ( !event.LeftIsDown() && !event.RightIsDown() && !event.MiddleIsDown() )
 
427
    {
 
428
        // Updating cursor
 
429
 
 
430
        DragPointData* DPD = FindDragPointAtPos(event.GetX(),event.GetY());
 
431
 
 
432
        if ( DPD )
 
433
        {
 
434
                switch ( DPD->Type )
 
435
                {
 
436
                case LeftTop:
 
437
                case RightBtm:
 
438
                    SetCur(wxCURSOR_SIZENWSE);
 
439
                    break;
 
440
 
 
441
                case Top:
 
442
                case Btm:
 
443
                    SetCur(wxCURSOR_SIZENS);
 
444
                    break;
 
445
 
 
446
                case RightTop:
 
447
                case LeftBtm:
 
448
                    SetCur(wxCURSOR_SIZENESW);
 
449
                    break;
 
450
 
 
451
                case Left:
 
452
                case Right:
 
453
                    SetCur(wxCURSOR_SIZEWE);
 
454
                    break;
 
455
 
 
456
                default:
 
457
                    SetCur(wxCURSOR_ARROW);
 
458
                }
 
459
        }
 
460
        else
 
461
        {
 
462
            SetCur(wxCURSOR_ARROW);
 
463
        }
 
464
 
 
465
    }
 
466
}
 
467
 
 
468
void wxsItemEditorContent::OnMouseDraggingPointInit(wxMouseEvent& event)
 
469
{
 
470
    BlockFetch(true);
 
471
 
 
472
    if ( event.RightIsDown() || event.MiddleIsDown() || !event.LeftIsDown() )
 
473
    {
 
474
        m_MouseState = msIdle;
 
475
        return;
 
476
    }
 
477
 
 
478
    int DeltaX = event.GetX() - m_DragInitPosX;
 
479
    if ( DeltaX<0 ) DeltaX = -DeltaX;
 
480
    int DeltaY = event.GetY() - m_DragInitPosY;
 
481
    if ( DeltaY<0 ) DeltaY = -DeltaY;
 
482
 
 
483
    if ( DeltaX + DeltaY > m_MinDragDistance )
 
484
    {
 
485
        m_MouseState = msDraggingPoint;
 
486
    }
 
487
}
 
488
 
 
489
void wxsItemEditorContent::OnMouseDraggingPoint(wxMouseEvent& event)
 
490
{
 
491
    if ( event.RightIsDown() || event.MiddleIsDown() )
 
492
    {
 
493
        // Cancelling change
 
494
        for ( size_t i=0; i<m_DragPoints.Count(); i++ )
 
495
        {
 
496
            m_DragPoints[i]->PosX = m_DragPoints[i]->DragInitPosX;
 
497
            m_DragPoints[i]->PosY = m_DragPoints[i]->DragInitPosY;
 
498
        }
 
499
        m_MouseState = msIdle;
 
500
        return;
 
501
    }
 
502
 
 
503
    if ( !event.LeftIsDown() )
 
504
    {
 
505
        // Finalizing change
 
506
        m_Data->BeginChange();
 
507
 
 
508
        wxsBaseProperties* Props = m_CurDragPoint->Item->GetBaseProps();
 
509
        if ( Props )
 
510
        {
 
511
            DragPointData* leftTop = m_CurDragPoint->ItemPoints[LeftTop];
 
512
            DragPointData* rightBtm = m_CurDragPoint->ItemPoints[RightBtm];
 
513
            int OldPosX = leftTop->DragInitPosX;
 
514
            int OldPosY = leftTop->DragInitPosY;
 
515
            int OldSizeX = rightBtm->DragInitPosX - OldPosX;
 
516
            int OldSizeY = rightBtm->DragInitPosY - OldPosY;
 
517
            int NewPosX = leftTop->PosX;
 
518
            int NewPosY = leftTop->PosY;
 
519
            int NewSizeX = rightBtm->PosX - NewPosX;
 
520
            int NewSizeY = rightBtm->PosY - NewPosY;
 
521
 
 
522
            if ( NewSizeX < 0 )
 
523
            {
 
524
                NewPosX += NewSizeX;
 
525
                NewSizeX = -NewSizeX;
 
526
            }
 
527
 
 
528
            if ( NewSizeY < 0 )
 
529
            {
 
530
                NewPosY += NewSizeY;
 
531
                NewSizeY = -NewSizeY;
 
532
            }
 
533
 
 
534
            wxWindow* Preview = GetPreviewWindow(m_CurDragPoint->Item);
 
535
 
 
536
            if ( Preview )
 
537
            {
 
538
                if ( NewPosX!=OldPosX || NewPosY!=OldPosY )
 
539
                {
 
540
                    if ( m_CurDragItem->GetParent() && (m_CurDragItem->GetParent()->GetType() == wxsTSizer) )
 
541
                    {
 
542
                        Props->m_Position.SetPosition(wxDefaultPosition,Preview->GetParent());
 
543
                    }
 
544
                    else
 
545
                    {
 
546
                        if ( m_CurDragItem->GetParent() )
 
547
                        {
 
548
                            // Adjusting position to parent coordinates
 
549
                            int ParentPosX = 0, ParentPosY = 0, ParentSizeX = 0, ParentSizeY = 0;
 
550
                            if ( FindAbsoluteRect(m_CurDragItem->GetParent(),ParentPosX,ParentPosY,ParentSizeX,ParentSizeY) )
 
551
                            {
 
552
                                NewPosX -= ParentPosX;
 
553
                                NewPosY -= ParentPosY;
 
554
                                Props->m_Position.SetPosition(wxPoint(NewPosX,NewPosY),Preview->GetParent());
 
555
                            }
 
556
                        }
 
557
                        else
 
558
                        {
 
559
                            // TODO: Update default position of window
 
560
                        }
 
561
                    }
 
562
                }
 
563
 
 
564
                if ( NewSizeX!=OldSizeX || NewSizeY!=OldSizeY )
 
565
                {
 
566
                    Props->m_Size.SetSize(wxSize(NewSizeX,NewSizeY),Preview->GetParent());
 
567
                }
 
568
            }
 
569
        }
 
570
 
 
571
        m_MouseState = msIdle;
 
572
        m_Data->EndChange();
 
573
        return;
 
574
    }
 
575
 
 
576
    int DeltaX = event.GetX() - m_DragInitPosX;
 
577
    int DeltaY = event.GetY() - m_DragInitPosY;
 
578
 
 
579
    DragPointData* leftTop = m_CurDragPoint->ItemPoints[LeftTop];
 
580
    DragPointData* rightBtm = m_CurDragPoint->ItemPoints[RightBtm];
 
581
 
 
582
    int Dummy = 0;
 
583
    switch ( m_CurDragPoint->Type )
 
584
    {
 
585
        case LeftTop:
 
586
            leftTop->PosX = leftTop->DragInitPosX + DeltaX;
 
587
            leftTop->PosY = leftTop->DragInitPosY + DeltaY;
 
588
            GridFixupForGlobalCoordinates(leftTop->PosX,leftTop->PosY,m_CurDragItem);
 
589
            break;
 
590
 
 
591
        case Top:
 
592
            leftTop->PosY = leftTop->DragInitPosY + DeltaY;
 
593
            GridFixupForGlobalCoordinates(Dummy,leftTop->PosY,m_CurDragItem);
 
594
            break;
 
595
 
 
596
        case RightTop:
 
597
            rightBtm->PosX = rightBtm->DragInitPosX + DeltaX;
 
598
            leftTop->PosY = leftTop->DragInitPosY + DeltaY;
 
599
            GridFixupForGlobalCoordinates(rightBtm->PosX,leftTop->PosY,m_CurDragItem);
 
600
            break;
 
601
 
 
602
        case Left:
 
603
            leftTop->PosX = leftTop->DragInitPosX + DeltaX;
 
604
            GridFixupForGlobalCoordinates(leftTop->PosX,Dummy,m_CurDragItem);
 
605
            break;
 
606
 
 
607
        case Right:
 
608
            rightBtm->PosX = rightBtm->DragInitPosX + DeltaX;
 
609
            GridFixupForGlobalCoordinates(rightBtm->PosX,Dummy,m_CurDragItem);
 
610
            break;
 
611
 
 
612
        case LeftBtm:
 
613
            leftTop->PosX = leftTop->DragInitPosX + DeltaX;
 
614
            rightBtm->PosY = rightBtm->DragInitPosY + DeltaY;
 
615
            GridFixupForGlobalCoordinates(leftTop->PosX,rightBtm->PosY,m_CurDragItem);
 
616
            break;
 
617
 
 
618
        case Btm:
 
619
            rightBtm->PosY = rightBtm->DragInitPosY + DeltaY;
 
620
            GridFixupForGlobalCoordinates(Dummy,rightBtm->PosY,m_CurDragItem);
 
621
            break;
 
622
 
 
623
        case RightBtm:
 
624
            rightBtm->PosX = rightBtm->DragInitPosX + DeltaX;
 
625
            rightBtm->PosY = rightBtm->DragInitPosY + DeltaY;
 
626
            GridFixupForGlobalCoordinates(rightBtm->PosX,rightBtm->PosY,m_CurDragItem);
 
627
            break;
 
628
 
 
629
        default:;
 
630
    }
 
631
 
 
632
    int LX = leftTop->PosX;
 
633
    int LY = leftTop->PosY;
 
634
    int RX = rightBtm->PosX;
 
635
    int RY = rightBtm->PosY;
 
636
 
 
637
    DragPointData** ItemPoints = leftTop->ItemPoints;
 
638
 
 
639
    ItemPoints[Top]->PosX = (LX+RX)/2;
 
640
    ItemPoints[Top]->PosY = LY;
 
641
    ItemPoints[RightTop]->PosX = RX;
 
642
    ItemPoints[RightTop]->PosY = LY;
 
643
    ItemPoints[Left]->PosX = LX;
 
644
    ItemPoints[Left]->PosY = (LY+RY) / 2;
 
645
    ItemPoints[Right]->PosX = RX;
 
646
    ItemPoints[Right]->PosY = (LY+RY) / 2;
 
647
    ItemPoints[LeftBtm]->PosX = LX;
 
648
    ItemPoints[LeftBtm]->PosY = RY;
 
649
    ItemPoints[Btm]->PosX = (LX+RX)/2;
 
650
    ItemPoints[Btm]->PosY = RY;
 
651
    FastRepaint();
 
652
}
 
653
 
 
654
void wxsItemEditorContent::OnMouseDraggingItemInit(wxMouseEvent& event)
 
655
{
 
656
    BlockFetch(true);
 
657
 
 
658
    if ( event.RightIsDown() || event.MiddleIsDown() || !event.LeftIsDown() )
 
659
    {
 
660
        m_MouseState = msIdle;
 
661
        return;
 
662
    }
 
663
 
 
664
    int DeltaX = event.GetX() - m_DragInitPosX;
 
665
    if ( DeltaX<0 ) DeltaX = -DeltaX;
 
666
    int DeltaY = event.GetY() - m_DragInitPosY;
 
667
    if ( DeltaY<0 ) DeltaY = -DeltaY;
 
668
 
 
669
    if ( DeltaX + DeltaY > m_MinDragDistance )
 
670
    {
 
671
        m_MouseState = msDraggingItem;
 
672
        m_Assist->NewDragging();
 
673
        SetCur(wxCURSOR_SIZING);
 
674
    }
 
675
}
 
676
 
 
677
void wxsItemEditorContent::OnMouseDraggingItem(wxMouseEvent& event)
 
678
{
 
679
    if ( event.RightIsDown() || event.MiddleIsDown() )
 
680
    {
 
681
        // Cancelling change
 
682
        for ( size_t i=0; i<m_DragPoints.Count(); i++ )
 
683
        {
 
684
            m_DragPoints[i]->PosX = m_DragPoints[i]->DragInitPosX;
 
685
            m_DragPoints[i]->PosY = m_DragPoints[i]->DragInitPosY;
 
686
        }
 
687
        m_MouseState = msIdle;
 
688
        m_AssistParent = 0;
 
689
        m_AssistTarget = 0;
 
690
        m_AssistAddAfter = false;
 
691
        m_Assist->NewDragging();
 
692
        return;
 
693
    }
 
694
 
 
695
    if ( !event.LeftIsDown() )
 
696
    {
 
697
        if ( !m_CurDragPoint )
 
698
        {
 
699
            // TODO: Enable this anti-crash check after tests
 
700
//            return;
 
701
        }
 
702
 
 
703
        // Finalizing change
 
704
        m_Data->BeginChange();
 
705
 
 
706
        if ( m_CurDragPoint->PosX != m_CurDragPoint->DragInitPosX ||
 
707
             m_CurDragPoint->PosY != m_CurDragPoint->DragInitPosY )
 
708
        {
 
709
            wxsParent* NewParent = 0;
 
710
            wxsItem* AtCursor = 0;
 
711
            bool AddAfter = true;
 
712
            if ( FindDraggingItemTarget(event.GetX(),event.GetY(),m_CurDragItem,NewParent,AtCursor,AddAfter) )
 
713
            {
 
714
                if ( (m_CurDragItem->GetParent() == NewParent) ||
 
715
                     (NewParent->CanAddChild(m_CurDragItem,false) &&
 
716
                      m_CurDragItem->CanAddToParent(NewParent,false)) )
 
717
                {
 
718
                    wxsParent* CurParent = m_CurDragItem->GetParent();
 
719
 
 
720
                    if ( CurParent != NewParent || NewParent->GetType() == wxsTSizer )
 
721
                    {
 
722
                        if ( AtCursor != m_CurDragItem )
 
723
                        {
 
724
                            // Storing extra data
 
725
                            int CurIndex = CurParent->GetChildIndex(m_CurDragItem);
 
726
                            TiXmlElement ExtraData("extra");
 
727
                            CurParent->StoreExtraData(CurIndex,&ExtraData);
 
728
 
 
729
                            // Unbinding from old parent
 
730
                            m_CurDragItem->GetParent()->UnbindChild(m_CurDragItem);
 
731
 
 
732
                            // Adding to new one
 
733
                            int NewIndex = -1;
 
734
                            if ( AtCursor )
 
735
                            {
 
736
                                NewIndex = NewParent->GetChildIndex(AtCursor);
 
737
                                if ( AddAfter ) NewIndex++;
 
738
                            }
 
739
 
 
740
                            NewParent->AddChild(m_CurDragItem,NewIndex);
 
741
 
 
742
                            // Restoring extra data
 
743
                            NewIndex = NewParent->GetChildIndex(m_CurDragItem);
 
744
                            NewParent->RestoreExtraData(NewIndex,&ExtraData);
 
745
                        }
 
746
                    }
 
747
 
 
748
                    wxsBaseProperties* Props = m_CurDragItem->GetBaseProps();
 
749
                    if ( Props )
 
750
                    {
 
751
                        if ( NewParent->GetType() == wxsTSizer )
 
752
                        {
 
753
                            Props->m_Position.SetPosition(wxDefaultPosition,0);
 
754
                        }
 
755
                        else
 
756
                        {
 
757
                            // Calculating new position
 
758
                            int ParentPosX = 0, ParentPosY = 0, ParentSizeX = 0, ParentSizeY = 0;
 
759
                            if ( FindAbsoluteRect(NewParent,ParentPosX,ParentPosY,ParentSizeX,ParentSizeY) )
 
760
                            {
 
761
                                int NewPosX = m_CurDragPoint->ItemPoints[LeftTop]->PosX - ParentPosX;
 
762
                                int NewPosY = m_CurDragPoint->ItemPoints[LeftTop]->PosY - ParentPosY;
 
763
                                wxWindow* PreviewParent = GetPreviewWindow(NewParent);
 
764
                                GridFixup(PreviewParent,NewPosX,NewPosY);
 
765
                                if ( PreviewParent )
 
766
                                {
 
767
                                    Props->m_Position.SetPosition(wxPoint(NewPosX,NewPosY),PreviewParent);
 
768
                                }
 
769
                            }
 
770
                        }
 
771
                    }
 
772
                }
 
773
            }
 
774
        }
 
775
        m_MouseState = msIdle;
 
776
        m_AssistTarget = 0;
 
777
        m_AssistParent = 0;
 
778
        m_AssistAddAfter = false;
 
779
        m_Assist->NewDragging();
 
780
        m_Data->EndChange();
 
781
        return;
 
782
    }
 
783
 
 
784
    int DeltaX = event.GetX() - m_DragInitPosX;
 
785
    int DeltaY = event.GetY() - m_DragInitPosY;
 
786
 
 
787
    if ( !FindDraggingItemTarget(event.GetX(),event.GetY(),m_CurDragItem,m_AssistParent,m_AssistTarget,m_AssistAddAfter) )
 
788
    {
 
789
        m_AssistTarget = 0;
 
790
        m_AssistParent = 0;
 
791
        m_AssistAddAfter = false;
 
792
    }
 
793
    else
 
794
    {
 
795
        // Applying grid stuff
 
796
        int ParentPosX = 0, ParentPosY = 0, ParentSizeX = 0, ParentSizeY = 0;
 
797
        if ( FindAbsoluteRect(m_AssistParent,ParentPosX,ParentPosY,ParentSizeX,ParentSizeY) )
 
798
        {
 
799
            int NewPosX = m_CurDragPoint->ItemPoints[LeftTop]->DragInitPosX - ParentPosX + DeltaX;
 
800
            int NewPosY = m_CurDragPoint->ItemPoints[LeftTop]->DragInitPosY - ParentPosY + DeltaY;
 
801
            int PosXStore = NewPosX;
 
802
            int PosYStore = NewPosY;
 
803
            wxWindow* PreviewParent = GetPreviewWindow(m_AssistParent);
 
804
            GridFixup(PreviewParent,NewPosX,NewPosY);
 
805
            if ( PreviewParent )
 
806
            {
 
807
                DeltaX += NewPosX - PosXStore;
 
808
                DeltaY += NewPosY - PosYStore;
 
809
            }
 
810
        }
 
811
 
 
812
    }
 
813
 
 
814
    for ( size_t i=0; i<m_DragPoints.Count(); i++ )
 
815
    {
 
816
        m_DragPoints[i]->PosX = m_DragPoints[i]->DragInitPosX + DeltaX;
 
817
        m_DragPoints[i]->PosY = m_DragPoints[i]->DragInitPosY + DeltaY;
 
818
    }
 
819
 
 
820
    FastRepaint();
 
821
}
 
822
 
 
823
void wxsItemEditorContent::OnMouseTargetSearch(wxMouseEvent& event)
 
824
{
 
825
    if ( event.RightDown() )
 
826
    {
 
827
        // Getting out of point-by-mouse state
 
828
        m_MouseState = msIdle;
 
829
        m_TargetInfo = 0;
 
830
        m_AssistParent = 0;
 
831
        m_AssistTarget = 0;
 
832
        m_AssistAddAfter = false;
 
833
        m_Assist->NewDragging();
 
834
        FastRepaint();
 
835
        return;
 
836
    }
 
837
 
 
838
    if ( event.LeftDown() )
 
839
    {
 
840
        // Adding item
 
841
        if ( m_AssistParent )
 
842
        {
 
843
            int Position = m_AssistParent->GetChildIndex(m_AssistTarget);
 
844
            if ( m_AssistAddAfter && Position>=0 )
 
845
            {
 
846
                Position++;
 
847
            }
 
848
            AddItemAtTarget(m_AssistParent,Position,m_TargetInfo,event.GetX(),event.GetY());
 
849
        }
 
850
        m_AssistParent = 0;
 
851
        m_AssistTarget = 0;
 
852
        m_AssistAddAfter = false;
 
853
        m_Assist->NewDragging();
 
854
 
 
855
        if ( !IsContinousInsert() )
 
856
        {
 
857
            m_MouseState = msIdle;
 
858
            m_TargetInfo = 0;
 
859
            FastRepaint();
 
860
        }
 
861
 
 
862
        return;
 
863
    }
 
864
 
 
865
    // highlight selection
 
866
    m_TargetX = event.GetX();
 
867
    m_TargetY = event.GetY();
 
868
    if ( !FindDraggingItemTarget(event.GetX(),event.GetY(),0,m_AssistParent,m_AssistTarget,m_AssistAddAfter) )
 
869
    {
 
870
        m_AssistTarget = 0;
 
871
        m_AssistParent = 0;
 
872
        m_AssistAddAfter = false;
 
873
    }
 
874
    FastRepaint();
 
875
}
 
876
 
 
877
bool wxsItemEditorContent::FindDraggingItemTarget(int PosX,int PosY,wxsItem* Dragging,wxsParent*& NewParent,wxsItem*& AtCursor,bool& AddAfter)
 
878
{
 
879
    // Searching for item at cursor position
 
880
    wxsItem* Cursor = FindItemAtPos(PosX,PosY,m_Data->GetRootItem());
 
881
    if ( !Cursor ) Cursor = m_Data->GetRootItem();
 
882
 
 
883
    // Avoiding shifting into dragged item
 
884
    wxsParent* DraggedAsParent = Dragging ? Dragging->ConvertToParent() : 0;
 
885
    if ( DraggedAsParent && DraggedAsParent->IsGrandChild(Cursor) )
 
886
    {
 
887
        // Can not drag into own child
 
888
        return false;
 
889
    }
 
890
 
 
891
    NewParent = Cursor->ConvertToParent();
 
892
 
 
893
    if ( NewParent && !::wxGetKeyState(WXK_ALT) )
 
894
    {
 
895
        AtCursor = 0;
 
896
        AddAfter = true;
 
897
        return true;
 
898
    }
 
899
 
 
900
    NewParent = Cursor->GetParent();
 
901
    if ( !NewParent )
 
902
    {
 
903
        // Should never be here, just in case
 
904
        return false;
 
905
    }
 
906
 
 
907
    if ( NewParent->GetType() == wxsTSizer )
 
908
    {
 
909
        AtCursor = Cursor;
 
910
        AddAfter = true;
 
911
 
 
912
        int ItemPosX;
 
913
        int ItemPosY;
 
914
        int ItemSizeX;
 
915
        int ItemSizeY;
 
916
        if ( FindAbsoluteRect(Cursor,ItemPosX,ItemPosY,ItemSizeX,ItemSizeY) )
 
917
        {
 
918
            // If cursor is on the left side, changing AddAfter flag to false
 
919
            if ( PosX < ItemPosX+(ItemSizeX/2) )
 
920
            {
 
921
                AddAfter = false;
 
922
            }
 
923
        }
 
924
    }
 
925
    else
 
926
    {
 
927
        AtCursor = 0;
 
928
        AddAfter = true;
 
929
    }
 
930
    return true;
 
931
}
 
932
 
 
933
void wxsItemEditorContent::BeforePreviewChanged()
 
934
{
 
935
    ClearMaps();
 
936
    ClearDragPoints();
 
937
    BeforeContentChanged();
 
938
}
 
939
 
 
940
void wxsItemEditorContent::AfterPreviewChanged()
 
941
{
 
942
    m_RebuildMaps = true;
 
943
    AfterContentChanged();
 
944
}
 
945
 
 
946
void wxsItemEditorContent::ScreenShootTaken()
 
947
{
 
948
    if ( m_RebuildMaps )
 
949
    {
 
950
        RecalculateMaps();
 
951
    }
 
952
    RebuildDragPoints();
 
953
    m_AssistParent = 0;
 
954
    m_AssistTarget = 0;
 
955
    m_AssistAddAfter = false;
 
956
    m_Assist->NewDragging();
 
957
}
 
958
 
 
959
wxWindow* wxsItemEditorContent::GetPreviewWindow(wxsItem* Item)
 
960
{
 
961
    if ( !Item ) return 0;
 
962
    ItemToWindowT::iterator i = m_ItemToWindow.find(Item);
 
963
    if ( i==m_ItemToWindow.end() ) return 0;
 
964
    return (*i).second;
 
965
}
 
966
 
 
967
void wxsItemEditorContent::ClearMaps()
 
968
{
 
969
    m_ItemToRect.clear();
 
970
    m_ItemToWindow.clear();
 
971
}
 
972
 
 
973
void wxsItemEditorContent::RecalculateMaps()
 
974
{
 
975
    m_ItemToRect.clear();
 
976
    m_ItemToWindow.clear();
 
977
    RecalculateMapsReq(m_Data->GetRootItem());
 
978
    m_RebuildMaps = false;
 
979
}
 
980
 
 
981
void wxsItemEditorContent::RecalculateMapsReq(wxsItem* Item)
 
982
{
 
983
    if ( Item->GetLastPreview() )
 
984
    {
 
985
        wxWindow* win = wxDynamicCast(Item->GetLastPreview(),wxWindow);
 
986
        if ( win )
 
987
        {
 
988
            m_ItemToWindow[Item] = win;
 
989
            if ( win->IsShown() )
 
990
            {
 
991
                int PosX = 0;
 
992
                int PosY = 0;
 
993
                int SizeX = 0;
 
994
                int SizeY = 0;
 
995
                win->GetPosition(&PosX,&PosY);
 
996
                win->GetParent()->ClientToScreen(&PosX,&PosY);
 
997
                ScreenToClient(&PosX,&PosY);
 
998
                CalcUnscrolledPosition(PosX,PosY,&PosX,&PosY);
 
999
                win->GetSize(&SizeX,&SizeY);
 
1000
                m_ItemToRect[Item] = wxRect(PosX,PosY,SizeX,SizeY);
 
1001
 
 
1002
                wxsParent* Parent = Item->ConvertToParent();
 
1003
                if ( Parent )
 
1004
                {
 
1005
                    for ( int i=0; i<Parent->GetChildCount(); i++ )
 
1006
                    {
 
1007
                        if ( Parent->IsChildPreviewVisible(Parent->GetChild(i)) )
 
1008
                        {
 
1009
                            RecalculateMapsReq(Parent->GetChild(i));
 
1010
                        }
 
1011
                    }
 
1012
                }
 
1013
            }
 
1014
        }
 
1015
    }
 
1016
}
 
1017
 
 
1018
void wxsItemEditorContent::InsertByPointing(const wxsItemInfo* Info)
 
1019
{
 
1020
    m_MouseState = msTargetSearch;
 
1021
    m_TargetInfo = Info;
 
1022
}
 
1023
 
 
1024
void wxsItemEditorContent::AddItemAtTarget(wxsParent* AssistParent,int Position,const wxsItemInfo* Info,int PosX,int PosY)
 
1025
{
 
1026
    wxsItem* New = wxsItemFactory::Build(Info->ClassName,m_Data);
 
1027
    if ( New )
 
1028
    {
 
1029
        if ( New->CanAddToParent(AssistParent,true) && AssistParent->CanAddChild(New,true) )
 
1030
        {
 
1031
            m_Data->BeginChange();
 
1032
            if ( AssistParent->AddChild(New,Position) )
 
1033
            {
 
1034
                wxsBaseProperties* Props = New->GetBaseProps();
 
1035
 
 
1036
                if ( AssistParent->GetType() == wxsTSizer )
 
1037
                {
 
1038
                    Props->m_Position.SetPosition(wxDefaultPosition,0);
 
1039
                }
 
1040
                else
 
1041
                {
 
1042
                    // Calculating new position
 
1043
                    int ParentPosX = 0, ParentPosY = 0, ParentSizeX = 0, ParentSizeY = 0;
 
1044
                    if ( FindAbsoluteRect(AssistParent,ParentPosX,ParentPosY,ParentSizeX,ParentSizeY) )
 
1045
                    {
 
1046
                        PosX -= ParentPosX;
 
1047
                        PosY -= ParentPosY;
 
1048
                        wxWindow* PreviewParent = GetPreviewWindow(AssistParent);
 
1049
                        GridFixup(PreviewParent,PosX,PosY);
 
1050
                        if ( PreviewParent )
 
1051
                        {
 
1052
                            Props->m_Position.SetPosition(wxPoint(PosX,PosY),PreviewParent);
 
1053
                        }
 
1054
                    }
 
1055
                }
 
1056
 
 
1057
                m_Data->SelectItem(New,true);
 
1058
            }
 
1059
            else
 
1060
            {
 
1061
                delete New;
 
1062
            }
 
1063
            m_Data->EndChange();
 
1064
            return;
 
1065
        }
 
1066
        delete New;
 
1067
    }
 
1068
}
 
1069
 
 
1070
void wxsItemEditorContent::GridFixup(wxWindow* PreviewWindow,int& PosX,int& PosY)
 
1071
{
 
1072
    if ( PreviewWindow && wxDynamicCast(PreviewWindow,wxsGridPanel) )
 
1073
    {
 
1074
        int GridSize = wxsGridPanel::GetGridSize();
 
1075
        if ( GridSize > 1 )
 
1076
        {
 
1077
            PosX = ( ( PosX + GridSize/2 ) / GridSize ) * GridSize;
 
1078
            PosY = ( ( PosY + GridSize/2 ) / GridSize ) * GridSize;
 
1079
        }
 
1080
    }
 
1081
}
 
1082
 
 
1083
void wxsItemEditorContent::GridFixupForGlobalCoordinates(int& PosX,int& PosY,wxsItem* Owner)
 
1084
{
 
1085
    if ( Owner )
 
1086
    {
 
1087
        wxsParent* Parent = Owner->GetParent();
 
1088
        if ( Parent )
 
1089
        {
 
1090
            int ParentPosX = 0, ParentPosY = 0, ParentSizeX = 0, ParentSizeY = 0;
 
1091
            if ( FindAbsoluteRect(Parent,ParentPosX,ParentPosY,ParentSizeX,ParentSizeY) )
 
1092
            {
 
1093
                PosX -= ParentPosX;
 
1094
                PosY -= ParentPosY;
 
1095
                wxWindow* PreviewParent = GetPreviewWindow(Parent);
 
1096
                GridFixup(PreviewParent,PosX,PosY);
 
1097
                PosX += ParentPosX;
 
1098
                PosY += ParentPosY;
 
1099
            }
 
1100
        }
 
1101
    }
 
1102
}
 
1103
 
 
1104
bool wxsItemEditorContent::IsContinousInsert()
 
1105
{
 
1106
    return Manager::Get()->GetConfigManager(_T("wxsmith"))->ReadBool(_T("/continousinsert"),false);
 
1107
}
 
1108
 
 
1109
void wxsItemEditorContent::OnKeyDown(wxKeyEvent& event)
 
1110
{
 
1111
    GetParent()->ProcessEvent(event);
 
1112
}
 
1113