2 * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
4 * ShapeFusion is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * ShapeFusion is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with ShapeFusion; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "FrameView.h"
20 #include "utilities.h"
22 DEFINE_EVENT_TYPE(wxEVT_FRAMEVIEW_DRAG)
24 BEGIN_EVENT_TABLE(FrameView, wxScrolledWindow)
25 EVT_PAINT(FrameView::OnPaint)
26 EVT_LEFT_DOWN(FrameView::OnDrag)
27 EVT_LEFT_UP(FrameView::OnDrag)
28 EVT_MOTION(FrameView::OnDrag)
29 EVT_SIZE(FrameView::OnSize)
32 FrameView::FrameView(wxWindow *parent, wxWindowID id):
33 wxScrolledWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER | wxFULL_REPAINT_ON_RESIZE),
34 mFrame(NULL), mEncBmp(NULL), mColorTable(NULL), mPanning(false), mDraggingOrigin(false), mDraggingKey(false), mNearOrigin(false), mNearKey(false)
36 SetBackgroundColour(wxColour(255, 255, 255));
38 EnableScrolling(false, false);
40 mOriginPen.SetColour(0, 128, 128);
42 mKeypointPen.SetColour(128, 0, 128);
44 mPanCursor = wxCursor(wxCURSOR_ARROW);
45 mPointCursor = wxCursor(wxCURSOR_CROSS);
46 mWhiteTransparency = true;
47 mCenterOrigin = false;
50 void FrameView::OnPaint(wxPaintEvent& e)
52 wxPaintDC tempdc(this);
55 GetVirtualSize(&vw, &vh);
57 GetClientSize(&cw, &ch);
58 if (mFrame != NULL && mColorTable != NULL) {
59 if (mEncBmp != NULL) {
60 int origin_x, origin_y;
63 origin_x = vw/2 - mFrame->OriginX();
64 origin_y = vh/2 - mFrame->OriginY();
66 origin_x = vw/2 - mDecBmp.GetWidth()/2;
67 origin_y = vh/2 - mDecBmp.GetHeight()/2;
70 tempdc.DrawBitmap(mDecBmp, origin_x, origin_y);
72 tempdc.SetPen(mOriginPen);
73 tempdc.CrossHair(mFrame->OriginX() + origin_x, mFrame->OriginY() + origin_y);
74 tempdc.DrawCircle(mFrame->OriginX() + origin_x, mFrame->OriginY() + origin_y, 2);
75 // mark bitmap keypoint
76 tempdc.SetPen(mKeypointPen);
77 tempdc.CrossHair(mFrame->KeyX() + origin_x, mFrame->KeyY() + origin_y);
78 tempdc.DrawCircle(mFrame->KeyX() + origin_x, mFrame->KeyY() + origin_y, 2);
79 // origin & key labels
80 wxString origin_label = wxT("Origin"),
81 key_label = wxT("Keypoint");
82 int text1w, text1h, text2w, text2h;
84 tempdc.SetFont(*wxSMALL_FONT);
85 tempdc.GetTextExtent(origin_label, &text1w, &text1h);
86 tempdc.GetTextExtent(key_label, &text2w, &text2h);
87 tempdc.SetTextForeground(wxColour(0, 128, 128));
88 if (mFrame->OriginY() + origin_y >= text1h + 2)
89 tempdc.DrawText(origin_label, vw - text1w - 2, mFrame->OriginY() + origin_y - text1h - 2);
91 tempdc.DrawText(origin_label, vw - text1w - 2, mFrame->OriginY() + origin_y + 2);
92 tempdc.SetTextForeground(wxColour(128, 0, 128));
93 if (mFrame->KeyY() + origin_y >= text2h + 2)
94 tempdc.DrawText(key_label, vw - text2w - 2, mFrame->KeyY() + origin_y - text2h - 2);
96 tempdc.DrawText(key_label, vw - text2w - 2, mFrame->KeyY() + origin_y + 2);
98 wxString no_bmp_label = wxT("No associated bitmap");
100 origin_x = vw/2, origin_y = vh/2;
102 tempdc.GetTextExtent(no_bmp_label, &text_w, &text_h);
103 origin_x -= text_w / 2;
104 origin_y -= text_h / 2;
105 tempdc.SetTextForeground(wxColour(255, 0, 0));
106 tempdc.DrawText(no_bmp_label, origin_x, origin_y);
111 // handle mouse drag (pan view, edit origin/keypoint)
112 void FrameView::OnDrag(wxMouseEvent &e)
114 if (mFrame == NULL || mEncBmp == NULL || mCenterOrigin)
117 if (e.ButtonDown()) {
118 int scroll_x, scroll_y;
120 GetViewStart(&scroll_x, &scroll_y);
122 // start dragging origin
123 mDraggingOrigin = true;
124 } else if (mNearKey) {
125 // start dragging keypoint
130 mDragStartX = e.GetPosition().x + scroll_x;
131 mDragStartY = e.GetPosition().y + scroll_y;
133 } else if (e.Dragging()) {
136 int dx = mDragStartX - e.GetPosition().x,
137 dy = mDragStartY - e.GetPosition().y;
140 } else if (mDraggingOrigin) {
142 int vw, vh, scroll_x, scroll_y, origin_x, origin_y;
144 GetVirtualSize(&vw, &vh);
145 GetViewStart(&scroll_x, &scroll_y);
146 origin_x = vw/2 - mDecBmp.GetWidth()/2;
147 origin_y = vh/2 - mDecBmp.GetHeight()/2;
148 mFrame->SetOriginX(e.GetPosition().x + scroll_x - origin_x);
149 mFrame->SetOriginY(e.GetPosition().y + scroll_y - origin_y);
150 // send an event so that other gui elements can update
151 wxCommandEvent event(wxEVT_FRAMEVIEW_DRAG, GetId());
153 event.SetEventObject(this);
155 GetEventHandler()->ProcessEvent(event);
157 } else if (mDraggingKey) {
159 int vw, vh, scroll_x, scroll_y, origin_x, origin_y;
161 GetVirtualSize(&vw, &vh);
162 GetViewStart(&scroll_x, &scroll_y);
163 origin_x = vw/2 - mDecBmp.GetWidth()/2;
164 origin_y = vh/2 - mDecBmp.GetHeight()/2;
165 mFrame->SetKeyX(e.GetPosition().x + scroll_x - origin_x);
166 mFrame->SetKeyY(e.GetPosition().y + scroll_y - origin_y);
167 // send an event so that other gui elements can update
168 wxCommandEvent event(wxEVT_FRAMEVIEW_DRAG, GetId());
170 event.SetEventObject(this);
172 GetEventHandler()->ProcessEvent(event);
175 } else if (e.ButtonUp()) {
176 mPanning = mDraggingOrigin = mDraggingKey = false;
177 } else if (e.Moving()) {
178 // mouse moved without buttons
179 int vw, vh, scroll_x, scroll_y;
181 GetVirtualSize(&vw, &vh);
182 GetViewStart(&scroll_x, &scroll_y);
184 int origin_x = vw/2 - mDecBmp.GetWidth()/2,
185 origin_y = vh/2 - mDecBmp.GetHeight()/2,
186 x = e.GetPosition().x + scroll_x,
187 y = e.GetPosition().y + scroll_y,
193 delta_x = x - (mFrame->OriginX() + origin_x);
194 delta_y = y - (mFrame->OriginY() + origin_y);
195 dist_origin = delta_x*delta_x + delta_y*delta_y;
196 delta_x = x - (mFrame->KeyX() + origin_x);
197 delta_y = y - (mFrame->KeyY() + origin_y);
198 dist_keypoint = delta_x*delta_x + delta_y*delta_y;
199 // are we near origin or keypoint?
200 if (dist_origin < 25) {
201 SetCursor(mPointCursor);
204 } else if (dist_keypoint < 25) {
205 SetCursor(mPointCursor);
209 SetCursor(mPanCursor);
210 mNearOrigin = mNearKey = false;
215 void FrameView::OnSize(wxSizeEvent &e)
218 vw = (mFrame == NULL || mEncBmp == NULL || mCenterOrigin) ? 0 : mEncBmp->Width(),
219 vh = (mFrame == NULL || mEncBmp == NULL || mCenterOrigin) ? 0 : mEncBmp->Height();
221 GetClientSize(&cw, &ch);
222 if (mEncBmp != NULL && mEncBmp->Pixels() != NULL) {
231 SetVirtualSize(vw, vh);
234 void FrameView::SetTranspPixelsDisplay(bool show)
236 mWhiteTransparency = show;
241 void FrameView::SetCenterOrigin(bool center)
243 mCenterOrigin = center;
249 void FrameView::SetFrame(ShapesFrame *fp)
256 ShapesFrame *FrameView::GetFrame(void) const
261 // associate a bitmap to display (we could do this in SetFrame
262 // but we would need a pointer to the original Shapes object)
263 void FrameView::SetBitmap(ShapesBitmap *bp)
267 GetClientSize(&cw, &ch);
270 if (bp->Pixels() != NULL) {
273 SetVirtualSize(cw, ch);
275 // adjust sizes to make scrolling work
276 int vw = mEncBmp->Width(),
277 vh = mEncBmp->Height();
283 SetVirtualSize(vw, vh);
286 if (mColorTable != NULL) {
287 wxImage img = ShapesBitmapToImage(bp, mColorTable, mWhiteTransparency);
289 // apply transformations
291 if (mFrame->IsXmirrored())
292 img = img.Mirror(true);
293 if (mFrame->IsYmirrored())
294 img = img.Mirror(false);
296 mDecBmp = wxBitmap(img);
300 wxLogError(wxT("[FrameView] Added a bitmap with NULL pixels"));
301 SetVirtualSize(cw, ch);
304 SetVirtualSize(cw, ch);
308 // call this before Set'tingBitmap!
309 void FrameView::SetColorTable(ShapesColorTable *ct)