1 //#**************************************************************
2 //# filename: BEBeamGetDKappa1.h
3 //#
4 //# author: Gerstmayr, Vetyukov
5 //#
6 //# generated:
7 //# description:
8 //# comments:
9 //#
10 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian
11 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the
12 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved.
13 //#
14 //# This file is part of HotInt.
15 //# HotInt is free software: you can redistribute it and/or modify it under the terms of
16 //# the HOTINT license. See folder 'licenses' for more details.
17 //#
18 //# bug reports are welcome!!!
19 //# WWW: www.hotint.org
20 //# email: bug_reports@hotint.org or support@hotint.org
21 //#***************************************************************************************
22
23
24 #include "stdafx.h"
25 #include "WCDriver3DDlg.h"
26 #include "WCDriver3D.h"
27 #include "DrawWindow2D.h"
28 #include "savewindowbitmap.h"
29
30
31
32 const int LOGICAL_PER_PIXEL = 10;
33 const double PIXELS_PER_REAL_UNIT = 8.;
34 const int DEFAULT_FONT_SIZE = 18; // should be about PIXELS_PER_REAL_UNIT * 3
35
36 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 // class CDrawWindow2DView: derived View class for the 2D - PlotWindow ( Control elements ) * 2012-12-12 +
39 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 // derived class for CDrawWindow2DView
IMPLEMENT_DYNCREATE(CDrawWindow2DView,MyBaseDialogForView)42 IMPLEMENT_DYNCREATE(CDrawWindow2DView, MyBaseDialogForView)
43
44 CDrawWindow2DView::CDrawWindow2DView(CWnd* parent)
45 {
46 m_pParent = (CDrawWindow2DDlg*) parent;
47 Reset();
48 }
49
ErrorMessage(mystr & msg)50 void CDrawWindow2DView::ErrorMessage(mystr& msg)
51 {
52 this->GetParentDlg()->GetWCDI()->GetUserInterface()->AddText( mystr("Illegal pDC - ") + caller );
53 }
54
Reset()55 void CDrawWindow2DView::Reset()
56 {
57 pts_y_top = 50;
58 pts_y_plot = 2000;
59 pts_y_bottom = 50;
60 pts_x_left = 50;
61 pts_x_plot = 2000;
62 pts_x_right = 50;
63 }
64
BEGIN_MESSAGE_MAP(CDrawWindow2DView,CMyBase2DView)65 BEGIN_MESSAGE_MAP(CDrawWindow2DView, CMyBase2DView)
66 ON_WM_MOUSEWHEEL()
67 ON_WM_MOUSEMOVE()
68 ON_WM_NCMOUSEMOVE()
69 ON_WM_LBUTTONDOWN()
70 ON_WM_LBUTTONUP()
71 END_MESSAGE_MAP()
72
73 // ***********************************************
74 // WINDOW PROPERTIES & ADDITIONAL DISPLAY ELEMENTS
75 // ***********************************************
76 BOOL CDrawWindow2DView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
77 {
78 // class specific
79 // no effect for Shift or Ctrl key, always zoom for both directions
80 UINT nFlags_specific = nFlags &!MK_SHIFT &!MK_CONTROL;
81
82 BOOL rv = CMyBase2DView::OnMouseWheel(nFlags_specific,zDelta,pt); // this already sets Shownrange in CMyBase2DView::ReComputeShownRange_Zooming
83
84 ReComputeZoomFactor(); // compute the new currentzoomfactor
85
86 SetCaller(mystr("REDRAW triggered by CDrawWindow2DView::OnMouseWheel\n"));
87
88 return RedrawWindow();
89 }
90
OnLButtonDown(UINT nFlags,CPoint point)91 void CDrawWindow2DView::OnLButtonDown(UINT nFlags, CPoint point)
92 {
93 DragDropStart() = point;
94 CView::OnLButtonDown(nFlags, point);
95 }
96
OnLButtonUp(UINT nFlags,CPoint point)97 void CDrawWindow2DView::OnLButtonUp(UINT nFlags, CPoint point)
98 {
99 AllowRedraw();
100 DragDropFinal() = point;
101
102 // catch Object at mouseposition
103 int nr_nearest = this->CatchDrawObject(point);
104 if(nr_nearest>0)
105 {
106 // determine if the nearest element is a IOGUIResponse
107 ControlWindowContext_::DrawComponent& elem = m_pParent->GetElement(nr_nearest);
108
109 int elnr = elem.mbs_elnr;
110 int is_response_element = GetParentDlg()->pWCDI->CallCompFunction(30, elnr, 0); // 0 to determine elementtype
111 if (is_response_element)
112 {
113 this->GetParentDlg()->pWCDI->CallCompFunction(30, elnr, 1, NULL); // decode "1" to "single left button (mouse)click"
114 GetParentDlg()->ForceUpdate();
115 }
116 }
117 else
118 {
119 // standard drag drop - drag drop end
120 DragDropAction();
121 SetCaller(mystr("REDRAW triggered by CMyBase2DView::OnLButtonUp\n"));
122 RedrawWindow();
123 }
124 CView::OnLButtonUp(nFlags, point);
125 }
126
OnMouseMove(UINT nFlags,CPoint point)127 void CDrawWindow2DView::OnMouseMove(UINT nFlags, CPoint point)
128 {
129 if ((nFlags & MK_LBUTTON) && !(nFlags & MK_SHIFT)) // left mouse button is down, shift key is up --> dragdrop --> animate
130 {
131 DragDropFinal() = point;
132 // check if distance for redraw is reached
133 double moved_x = DragDropFinal().x - DragDropStart().x;
134 double moved_y = DragDropFinal().y - DragDropStart().y;
135 double dragdropdistance = sqrt(moved_x*moved_x + moved_y*moved_y);
136
137 if (dragdropdistance > 10.)
138 {
139 DragDropAction();
140
141 int dbg_donotredraw = DoNotRedraw();
142 if(!DoNotRedraw()) // CATCH EXCEPTION - wincore.cpp l:248
143 {
144 SetCaller(mystr("REDRAW triggered by CDrawWindow2DView::OnMouseMove-DragDrop\n"));
145 RedrawWindow();
146 }
147 else
148 {
149 int caught = 1;
150 }
151 DragDropStart() = point;
152 }
153 }
154
155 CPoint capture_LOGICAL = GetLogicalFromPixels(point);
156
157 double x = XofLogical(capture_LOGICAL);
158 double y = YofLogical(capture_LOGICAL);
159 SetStatusBarText_X(mystr(" X: ") + mystr(x,4)); // to 4 digits
160 SetStatusBarText_Y(mystr(" Y: ") + mystr(y,4)); // to 4 digits
161
162 int nearest_obj = CatchDrawObject(point);
163 UpdateStatusBarInfo();
164
165 return CView::OnMouseMove(nFlags, point);
166 }
167
UpdateStatusBarInfo()168 void CDrawWindow2DView::UpdateStatusBarInfo()
169 {
170 if (selected_object_buffer > 0)
171 {
172 const ControlWindowContext_::DrawComponent& elem = GetParentDlg()->GetElement(selected_object_buffer);
173
174 if(elem.IsSelectable())
175 {
176 mystr description = mystr("Selectable Element: ");
177 int i = elem.sub_elnr / 65536; // input port number
178 //int j = elem.sub_elnr % 65536; // list index nrunningumber
179 switch (elem.sub_type)
180 {
181 case TElementFrame: description += mystr("Frame of MBS-Element # ") + mystr(elem.sub_elnr) + mystr("."); break;
182 case TElementName: description += mystr("Label of MBS-Element # ") + mystr(elem.sub_elnr) + mystr("."); break;
183 case TInputNode: description += mystr("InputNode #") + mystr(elem.sub_elnr) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
184 case TOutputNode: description += mystr("OutputNode #") + mystr(elem.sub_elnr) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
185 case TConstructionNode: description += mystr("ConstructionNode for input # ") + mystr(i) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
186 case TConnectionLine: description += mystr("ConnectionLine for input # ") + mystr(i) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
187 case TTextObject: description += mystr("TextObject #") + mystr(elem.sub_elnr) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
188 case TSymbol: description += mystr("ElementSymbol #") + mystr(elem.sub_elnr) + mystr(" (of MBS-Element # ") + mystr(elem.mbs_elnr) + mystr(")"); break;
189 default: description += mystr("NONE");
190 }
191 SetStatusBarText_Main(description);
192 }
193 else
194 SetStatusBarText_Main(mystr("")); // no selectable object
195 }
196 else
197 {
198 SetStatusBarText_Main(mystr("no selectable element"));
199 }
200 }
201
OnNcMouseMove(UINT nHitTest,CPoint point)202 void CDrawWindow2DView::OnNcMouseMove(UINT nHitTest, CPoint point)
203 {
204 // this is reached when mouse moves OFF the client rect
205 SetStatusBarText_X(mystr(""));
206 SetStatusBarText_Y(mystr(""));
207 CMyBase2DView::OnNcMouseMove(nHitTest, point);
208 }
209
DragDropAction()210 void CDrawWindow2DView::DragDropAction()
211 {
212 if (selected_object_buffer>0)
213 {
214 const ControlWindowContext_::DrawComponent& elem = GetParentDlg()->GetElement(selected_object_buffer);
215 ControlWindowContext_::DrawComponent& elem_nc = GetParentDlg() -> GetElement(selected_object_buffer);
216
217 if (elem.IsSelectableMBSElement() || elem.IsSelectableConstructionNode() )
218 {
219 // buffered element is MOVABLE independently - move only this element
220
221 CPoint logical_start = GetLogicalFromPixels(DragDropStart(),mystr("DragDropAction - StartPoint"));
222 CPoint logical_final = GetLogicalFromPixels(DragDropFinal(),mystr("DragDropAction - FinalPoint"));
223
224 double x_start = XofLogical(logical_start);
225 double y_start = YofLogical(logical_start);
226 double x_final = XofLogical(logical_final);
227 double y_final = YofLogical(logical_final);
228
229 double x_shift = x_final-x_start;
230 double y_shift = y_final-y_start;
231 int remember_selected_object_buffer = selected_object_buffer;
232
233 if (elem.IsSelectableMBSElement()) // entire Element is movable
234 {
235 int mbs_elem_nr = elem.mbs_elnr;
236 m_pParent -> GetWCDDlg() -> GetWCDInterface() -> MoveElement(mbs_elem_nr, x_shift, y_shift, 0.); // apply change of position
237 m_pParent -> ForceUpdate(); // redraw wich updated position
238 this->selected_object_buffer = remember_selected_object_buffer; // keep "selected object", has been updated during redraw
239 }
240
241 if (elem.IsSelectableConstructionNode()) // construction node is movable
242 {
243 int mbs_elem_nr = elem.mbs_elnr;
244 int list_idx = elem.sub_elnr % 65536; // last 16 bits of subelemnr code the array position to insert
245 m_pParent -> GetWCDDlg() -> GetWCDInterface() -> MoveConNode2D(mbs_elem_nr, list_idx, x_shift, y_shift);
246
247 //BOOL LeftMouseButtonDown = ( (GetKeyState(VK_LBUTTON) & 0x80) != 0 );
248 //if (LeftMouseButtonDown)
249 //{
250 // elem_nc.Center() += Vector2D(x_shift,y_shift);
251 // m_pParent->RedrawWindow();
252 //}
253 //else
254 //{
255 m_pParent -> ForceUpdate(); // redraw wich updated position
256 this->selected_object_buffer = remember_selected_object_buffer; // keep "selected object", has been updated during redraw
257 //}
258 }
259 // return CMyBase2DView::DragDropAction(); // under construction: replace this with moveobject2d ....
260
261 }
262 else
263 {
264 // buffered element is not movable independently - move entire sheet
265 return CMyBase2DView::DragDropAction();
266 }
267 }
268 else
269 {
270 // no element selected - move entire sheet
271 return CMyBase2DView::DragDropAction();
272 }
273 }
274
275 // *******************
276 // THE DRAWING PROCESS
277 // *******************
OnDraw(CDC * pDC)278 void CDrawWindow2DView::OnDraw(CDC* pDC)
279 {
280 // TRY TO CATCH MANY REDRAW MESSAGES
281 // delay redraw ??
282 MSG msg;
283 while(::PeekMessage(&msg, m_hWnd, WM_DRAWITEM, WM_DRAWITEM, PM_REMOVE))
284 {
285 int dbg=1;
286 }
287
288 // is redraw currently allowed ?
289 // Drawing could be prevented by: ForceUpdate, OnDraw
290 if(DoNotRedraw())
291 {
292 return;
293 }
294 ForbidRedraw();
295
296 _is_executing_ondraw = 0;
297
298 // reset caller string for any calls by system
299 SetCaller(mystr("REDRAW triggered by SYSTEM\n"));
300
301 CRect plotrect;
302 this->GetPlotRect(plotrect);
303
304 if(shownrange.Empty())
305 {
306 ComputeFullRange(1);
307 shownrange = fullrange;
308 }
309
310 if(0)
311 {
312 DrawElements(pDC);
313 }
314 else
315 {
316 CMyMemDC MDC(pDC);
317 DrawElements(&MDC);
318 }
319
320 _is_executing_ondraw = 0;
321 AllowRedraw();
322 }
323
DrawElements(CDC * pDC)324 void CDrawWindow2DView::DrawElements(CDC *pDC)
325 {
326 this->SelectDefaultFont(pDC, 20);
327
328 if(0) // HACK draw "+" at origin
329 {
330 pDC->MoveTo( ValuesToLogical(-.1,0.));
331 pDC->LineTo( ValuesToLogical( .1,0.));
332 pDC->MoveTo( ValuesToLogical(0.,-.1));
333 pDC->LineTo( ValuesToLogical(0., .1));
334 }
335
336 // DRAW the elements
337 int n = GetParentDlg()->NElements();
338 for (int i=1; i<=n; i++)
339 {
340 _is_executing_ondraw = n;
341 ControlWindowContext_::DrawComponent& elem = m_pParent->GetElement(i);
342 if (elem.IsLine()) { DrawLine(pDC,elem); }
343 else if (elem.IsRectangle()) { DrawRectangle(pDC,elem); }
344 else if (elem.IsEllipse()) { DrawEllipse(pDC,elem); }
345 else if (elem.IsText()) { DrawText(pDC,elem); }
346 }
347 }
348
IsVisible(CDC * pDC,ControlWindowContext_::DrawComponent & elem)349 BOOL CDrawWindow2DView::IsVisible(CDC* pDC, ControlWindowContext_::DrawComponent& elem)
350 {
351 // TODO: VISIBILITY CHECK
352 return true;
353 }
354
355 // Element based on a Line
DrawLine(CDC * pDC,ControlWindowContext_::DrawComponent & elem)356 BOOL CDrawWindow2DView::DrawLine(CDC* pDC, ControlWindowContext_::DrawComponent& elem)
357 {
358 // draws a line from Point1 (elem::center) to Point2 (elem::size)
359 // Pen for Line (color,thickness)
360 COLORREF col = (COLORREF) ((int)(elem.col(1)*255+0.5) + ((int)(elem.col(2)*255+0.5)<<8) + ((int)(elem.col(3)*255+0.5)<<16));
361 int thickness = ( elem.IsSymbol() ? LOGICAL_PER_PIXEL*50 : 1); // thin line for connection lines, thicker for symblos
362 CPen pen (PS_SOLID, thickness, col);
363 CPen* prevPen = pDC->SelectObject(&pen);
364
365 //draw
366 CPoint startpoint = ValuesToLogical(elem.P1().X(), elem.P1().Y());
367 CPoint endpoint = ValuesToLogical(elem.P2().X(), elem.P2().Y());
368 pDC->MoveTo(startpoint);
369 pDC->LineTo(endpoint);
370
371 // previous pen
372 pDC->SelectObject(prevPen);
373 return true;
374 }
375
376 // Element based on a Rectangular ( Frame of all elements )
DrawRectangle(CDC * pDC,ControlWindowContext_::DrawComponent & elem)377 BOOL CDrawWindow2DView::DrawRectangle(CDC* pDC, ControlWindowContext_::DrawComponent& elem)
378 {
379 // draw a rectangle
380 // Pen for Border (color,thickness)
381 COLORREF col = (COLORREF) ((int)(elem.col(1)*255+0.5) + ((int)(elem.col(2)*255+0.5)<<8) + ((int)(elem.col(3)*255+0.5)<<16));
382 int thickness = ( elem.IsSymbol() ? LOGICAL_PER_PIXEL*50 : 1); // thin line for connection lines, thicker for symblos
383 CPen pen(PS_SOLID, thickness, col);
384 CPen* prevPen = pDC->SelectObject(&pen);
385
386 // color for area
387 COLORREF col2;
388 if ( (elem.col2(1) < 0. || elem.col2(2) < 0. || elem.col2(3) < 0.) ) col2 = pDC->GetBkColor();
389 else col2 = (COLORREF) ((int)(elem.col2(1)*255+0.5) + ((int)(elem.col2(2)*255+0.5)<<8) + ((int)(elem.col2(3)*255+0.5)<<16));
390 CBrush brush(col2);
391 CBrush* prevBrush = pDC->SelectObject(&brush);
392
393 // draw
394 CPoint p1 = ValuesToLogical(elem.GetXMin(), elem.GetYMin());
395 CPoint p2 = ValuesToLogical(elem.GetXMax(), elem.GetYMax());
396 CRect rect(p1,p2);
397 pDC->Rectangle(rect);
398
399 // previous pen and brush
400 pDC->SelectObject(prevPen);
401 pDC->SelectObject(prevBrush);
402 return true;
403 }
404
405 // Element based on an Ellipse ( e.g. Nodes )
DrawEllipse(CDC * pDC,ControlWindowContext_::DrawComponent & elem)406 BOOL CDrawWindow2DView::DrawEllipse(CDC* pDC, ControlWindowContext_::DrawComponent& elem)
407 {
408 // draw an ellipse
409 // Pen for Border (color,thickness)
410 COLORREF col = (COLORREF) ((int)(elem.col(1)*255+0.5) + ((int)(elem.col(2)*255+0.5)<<8) + ((int)(elem.col(3)*255+0.5)<<16));
411 int thickness = ( elem.IsSymbol() ? LOGICAL_PER_PIXEL*50 : 1); // thin line for connection lines, thicker for symblos
412 CPen pen(PS_SOLID, thickness, col);
413 CPen* prevPen = pDC->SelectObject(&pen);
414
415 // color for area
416 COLORREF col2;
417 if ( (elem.col2(1) < 0. || elem.col2(2) < 0. || elem.col2(3) < 0.) ) col2 = pDC->GetBkColor();
418 else col2 = (COLORREF) ((int)(elem.col2(1)*255+0.5) + ((int)(elem.col2(2)*255+0.5)<<8) + ((int)(elem.col2(3)*255+0.5)<<16));
419 CBrush brush(col2);
420 CBrush* prevBrush = pDC->SelectObject(&brush);
421
422 //draw
423 CPoint p1 = ValuesToLogical(elem.GetXMin(), elem.GetYMin());
424 CPoint p2 = ValuesToLogical(elem.GetXMax(), elem.GetYMax());
425 CRect rect(p1,p2);
426 pDC->Ellipse(rect);
427
428 // previous pen and brush
429 pDC->SelectObject(prevPen);
430 pDC->SelectObject(prevBrush);
431 return true;
432 }
433
434 // Textbox
DrawText(CDC * pDC,ControlWindowContext_::DrawComponent & elem)435 BOOL CDrawWindow2DView::DrawText(CDC* pDC, ControlWindowContext_::DrawComponent& elem)
436 {
437 CPoint p1 = ValuesToLogical(elem.GetXMin(), elem.GetYMin());
438 CPoint p2 = ValuesToLogical(elem.GetXMax(), elem.GetYMax());
439 CRect rect(p1,p2);
440
441 // CATCH ir rect is too smal
442 if(abs(rect.Height()) < 15)
443 {
444 return false;
445 }
446
447 int fontsize= (int) (DEFAULT_FONT_SIZE * LOGICAL_PER_PIXEL * currentzoomfactor + 0.5);
448
449 if (elem.sub_type == TElementName) // element name beneath the Element
450 {
451 fontsize = (int) (DEFAULT_FONT_SIZE * LOGICAL_PER_PIXEL * currentzoomfactor + 0.5);
452 }
453 if (elem.sub_type == TSymbol) // text in center of element
454 {
455 fontsize = (int) (DEFAULT_FONT_SIZE * LOGICAL_PER_PIXEL * currentzoomfactor * 1.3 + 0.5);
456 }
457 if (elem.sub_type == TTextObject)
458 {
459 fontsize = (int) (DEFAULT_FONT_SIZE * LOGICAL_PER_PIXEL * currentzoomfactor + 0.5);
460 }
461
462 // check if font size is too small
463 if (fontsize == 0) fontsize = 1;
464
465 CFont* font = GetDefaultFont(pDC,fontsize);
466 CFont* prevFont = pDC->SelectObject(font);
467
468 // color for Text
469 COLORREF col = (COLORREF) ((int)(elem.col(1)*255+0.5) + ((int)(elem.col(2)*255+0.5)<<8) + ((int)(elem.col(3)*255+0.5)<<16));
470 COLORREF prevcolor = pDC->SetTextColor(col);
471
472 // Additional Debug output: Fontsize and textextent
473 CSize textsize = pDC->GetTextExtent(CString(elem.text));
474 this->SetStatusBarText_Main(mystr("BASE:") + mystr(DEFAULT_FONT_SIZE * LOGICAL_PER_PIXEL) + mystr(" FS:") + mystr(fontsize) + mystr(" ZF:") + mystr(currentzoomfactor));
475 this->SetStatusBarText_X(mystr(textsize.cx));
476 this->SetStatusBarText_Y(mystr(textsize.cy));
477 // Additional Debug output:
478
479 this->DrawTextInRect(pDC, CString(elem.text), rect, 0., elem.TextAllign());
480 // this->DrawTextAt(pDC, CString(elem.text), rect.CenterPoint(), CPoint( (int)(-textsize.cx*0.5), (int)(-textsize.cy*0.5)), 0., elem.TextAllign());
481
482 pDC->SelectObject(prevFont);
483 pDC->SetTextColor(prevcolor);
484 return true;
485 }
486
DoNotRedraw()487 int CDrawWindow2DView::DoNotRedraw()
488 {
489 return GetParentDlg()->DoNotRedraw();
490 }
ForbidRedraw()491 void CDrawWindow2DView::ForbidRedraw()
492 {
493 GetParentDlg()->ForbidRedraw();
494 }
AllowRedraw()495 void CDrawWindow2DView::AllowRedraw()
496 {
497 GetParentDlg()->AllowRedraw();
498 }
499
SetStatusBarText_Main(mystr text)500 void CDrawWindow2DView::SetStatusBarText_Main (mystr text) // slot1
501 {
502 if (!GetParentDlg()->m_flag_statusinfo) text = "";
503 (GetParentDlg()->m_StatusBar).SetText(text,1,0);
504 }
SetStatusBarText_X(mystr text)505 void CDrawWindow2DView::SetStatusBarText_X (mystr text) { (GetParentDlg()->m_StatusBar).SetText(text,2,0); } // slot2
SetStatusBarText_Y(mystr text)506 void CDrawWindow2DView::SetStatusBarText_Y (mystr text) { (GetParentDlg()->m_StatusBar).SetText(text,3,0); } // slot3
507
508
ReComputeZoomFactor()509 double CDrawWindow2DView::ReComputeZoomFactor()
510 {
511 currentzoomfactor = initshownrange.SizeX() / shownrange.SizeX();
512 if (currentzoomfactor<0 || currentzoomfactor>1e8)
513 return currentzoomfactor;
514 return currentzoomfactor;
515 }
516
SetInitialRange()517 void CDrawWindow2DView::SetInitialRange()
518 {
519 // real coordinate boundaries of scene
520 ComputeFullRange();
521
522 // available pixels
523 CRect curr; GetClientRect(curr);
524 long currHeight = abs(curr.Height());
525 long currWidth = abs(curr.Width());
526
527 // initial displayed range - chosen such that default IOElement has agreeable size...
528 double xmin = fullrange.Center().X() - (double)currWidth / PIXELS_PER_REAL_UNIT;
529 double xmax = fullrange.Center().X() + (double)currWidth / PIXELS_PER_REAL_UNIT;
530 double ymin = fullrange.Center().Y() - (double)currHeight / PIXELS_PER_REAL_UNIT;
531 double ymax = fullrange.Center().Y() + (double)currHeight / PIXELS_PER_REAL_UNIT;
532 SetShownRange(xmin, xmax, ymin, ymax);
533 initshownrange = Box2D(Vector2D(xmin, ymin), Vector2D(xmax, ymax));
534 currentzoomfactor = 1.;
535 }
536
537 // adjust the available logical points to the available pixels...
MatchLogicalPoints()538 void CDrawWindow2DView::MatchLogicalPoints()
539 {
540 // available pixels
541 CRect curr; GetClientRect(curr);
542 long currHeight = abs(curr.Height());
543 long currWidth = abs(curr.Width());
544
545 // set the range for logical points
546 int BM = 20; // base multiplicator -> 20 means that origin is at 5%
547 this->pts_x_left = 0; // currWidth * LOGICAL_PER_PIXEL * 1;
548 this->pts_x_plot = currWidth * LOGICAL_PER_PIXEL * BM; // currWidth * LOGICAL_PER_PIXEL * (BM-2);
549 this->pts_x_right = 0; // currWidth * LOGICAL_PER_PIXEL * 1;
550 this->pts_y_top = 0; // currHeight * LOGICAL_PER_PIXEL * 1;
551 this->pts_y_plot = currHeight * LOGICAL_PER_PIXEL * BM; // currHeight * LOGICAL_PER_PIXEL * (BM-2);
552 this->pts_y_bottom = 0; // currHeight * LOGICAL_PER_PIXEL * 1;
553 }
554
Rescale()555 void CDrawWindow2DView::Rescale()
556 {
557 CRect prev = prevClientRect;
558 long prevHeight = abs(prev.Height());
559 long prevWidth = abs(prev.Width());
560
561 CRect curr; GetClientRect(curr);
562 long currHeight = abs(curr.Height());
563 long currWidth = abs(curr.Width());
564
565 // scale the shown range to fit
566 // f.t.t.b. assume right/lower boundary is moved ( xmax, ymax )
567 // later could compare WindowRect instead of ClientRect to find out which border was moved
568 double stretchfactor = (double)abs(curr.Width()) / (double)abs(prev.Width());
569
570 Box2D prevshownrange = shownrange;
571 double near_x = shownrange.PMin().X(); // assumed to be same
572 double far_x = shownrange.PMin().X() + shownrange.SizeX()*(double)abs(curr.Width()) / (double)abs(prev.Width());
573 double near_y = shownrange.PMax().Y() - shownrange.SizeY()*(double)abs(curr.Height()) / (double)abs(prev.Height());
574 double far_y = shownrange.PMax().Y();
575 Box2D newshownrange(Vector2D(near_x,near_y),Vector2D(far_x,far_y));
576 SetShownRange(near_x, far_x, near_y, far_y);
577
578 Box2D previnitshownrange = initshownrange;
579 near_x = initshownrange.PMin().X(); // assumed to be same
580 far_x = initshownrange.PMin().X() + initshownrange.SizeX()*(double)abs(curr.Width()) / (double)abs(prev.Width());
581 near_y = initshownrange.PMax().Y() - initshownrange.SizeY()*(double)abs(curr.Height()) / (double)abs(prev.Height());
582 far_y = initshownrange.PMax().Y();
583 Box2D newinitshownrange(Vector2D(near_x,near_y),Vector2D(far_x,far_y));
584 initshownrange = newinitshownrange;
585
586 MatchLogicalPoints();
587 }
588
589 // computes limits of datasets - real values
ComputeFullRange(int flag_equal)590 void CDrawWindow2DView::ComputeFullRange(int flag_equal)
591 {
592 double xmin,xmax,ymin,ymax;
593 int n = GetParentDlg()->NElements();
594 if (n==0)
595 {
596 //fullrange.Clear();
597 fullrange=Box2D(Vector2D(-1,-1),Vector2D(1,1));
598 }
599 else
600 {
601 ControlWindowContext_::DrawComponent& elem1 = GetParentDlg()->GetElement(1);
602 xmin = elem1.GetXMin();
603 xmax = elem1.GetXMax();
604 ymin = elem1.GetYMin();
605 ymax = elem1.GetYMax();
606 for (int i=2; i<=n; i++)
607 {
608 ControlWindowContext_::DrawComponent& elem = GetParentDlg()->GetElement(i);
609 if (elem.GetXMin()<xmin) xmin = elem.GetXMin();
610 if (xmax<elem.GetXMax()) xmax = elem.GetXMax();
611 if (elem.GetYMin()<ymin) ymin = elem.GetYMin();
612 if (ymax<elem.GetYMax()) ymax = elem.GetYMax();
613 }
614 fullrange = Box2D( Vector2D(xmin,ymin), Vector2D(xmax,ymax) );
615
616 // make x and y axis intervals same size
617 if(flag_equal)
618 {
619 double ylog_by_xlog = (double) Get_YRange_logical() / (double) Get_XRange_logical();
620 double yran_by_xran = fullrange.SizeY() / fullrange.SizeX();
621 {
622 if(ylog_by_xlog < yran_by_xran)
623 {
624 // y-axis is fits, adjust x-axis
625 double middle = fullrange.Center().X();
626 double newrange = fullrange.SizeX() * yran_by_xran / ylog_by_xlog;
627 double newmin = middle - newrange * 0.5;
628 double newmax = middle + newrange * 0.5;
629
630 fullrange = Box2D(Vector2D(newmin,fullrange.PMin().Y()), Vector2D(newmax,fullrange.PMax().Y()));
631 }
632 else
633 {
634 // x-axis is fits, adjust y-axis
635 double middle = fullrange.Center().Y();
636 double newrange = fullrange.SizeY() / yran_by_xran * ylog_by_xlog;
637 double newmin = middle - newrange * 0.5;
638 double newmax = middle + newrange * 0.5;
639
640 fullrange = Box2D(Vector2D(fullrange.PMin().X(),newmin), Vector2D(fullrange.PMax().X(),newmax));
641 }
642 }
643 }
644 }
645 }
646
SetShownRange(double xmin,double xmax,double ymin,double ymax)647 void CDrawWindow2DView::SetShownRange(double xmin, double xmax, double ymin, double ymax)
648 {
649 shownrange = Box2D( Vector2D(xmin,ymin), Vector2D(xmax,ymax) );
650 }
651
652 // new code to catch the objects
CatchDrawObject(CPoint capture_PIXELS)653 int CDrawWindow2DView::CatchDrawObject( CPoint capture_PIXELS )
654 {
655 //CPoint capture_LOGICAL = GetLogicalFromPixels(capture_PIXELS, mystr("CatchDrawObject"));
656 //BOOL LeftMouseButtonDown = ( (GetKeyState(VK_LBUTTON) & 0x80) != 0 );
657
658 selected_object_buffer = 0;
659 int priority_buffer = 0;
660 int priority = 0; // option for multiple valid objects, pick the one with highest priority
661 int distance_buffer = 0xFFFFul; // option for multiple valid objects, pick the nearest ( priority is checked first )
662 int distance = 0xFFFFul;
663
664 // define a cutoff distance for each element type - distances that compute to more than this value cannot give focus
665 const int cutoff_response = 0;
666 const int cutoff_nodes = 30;
667 const int cutoff_lines = 20;
668 const int cutoff_rects = 0;
669
670 // define a priority order - rects over nodes over lines...
671 const int priority_response = 5;
672 const int priority_nodes = 3;
673 const int priority_lines = 1;
674 const int priority_rects = 5;
675
676 int n = GetParentDlg()->NElements();
677 if(n==0)
678 {
679 return 0; // empty list
680 }
681 else
682 {
683 //AD: only one loop, priority order as in the array ... 4
684 for(int i = 1; i<=n; i++)
685 {
686 ControlWindowContext_::DrawComponent& elem = GetParentDlg()->GetElement(i);
687 int distance = GetDistanceFromComponent(i,capture_PIXELS);
688
689 // only consider elements within the defined cutoff distance
690 if (elem.IsSymbol())
691 {
692 priority = priority_response;
693 if (distance>cutoff_response)
694 distance = 0xFFFFul;
695 }
696 else if (elem.IsEllipse())
697 {
698 priority = priority_nodes;
699 if (distance>cutoff_nodes)
700 distance = 0xFFFFul;
701 }
702 else if (elem.IsLine())
703 {
704 priority = priority_lines;
705 if (distance>cutoff_lines)
706 distance = 0xFFFFul;
707 }
708 else if (elem.IsRectangle())
709 {
710 priority = priority_response;
711 if (distance>cutoff_rects)
712 distance = 0xFFFFul;
713 }
714 else
715 {
716 priority = 0;
717 distance = 0xFFFFul;
718 }
719 // new selected object when Priority is same and distance is smaller OR priority is higher and distance is a valid number
720 if( (priority==priority_buffer && distance<distance_buffer) ||
721 (priority>priority_buffer && distance<0xFFFFul) )
722 {
723 selected_object_buffer = i;
724 priority_buffer = priority;
725 distance_buffer = distance;
726 }
727 }
728 return selected_object_buffer;
729 }
730 }
731
GetDistanceFromComponent(int i,CPoint capture_PIXELS)732 int CDrawWindow2DView::GetDistanceFromComponent(int i, CPoint capture_PIXELS)
733 {
734 //CPoint capture_LOGICAL = GetLogicalFromPixels(capture_PIXELS, mystr("CatchDrawObject"));
735
736 // checks distance IN PIXELS to the object ( line / rectangle / TODO: other shapes)
737 ControlWindowContext_::DrawComponent& elem = GetParentDlg()->GetElement(i);
738 int dist = 0xFFFFul;
739
740 // use the elements subtype to decide which shape must be checked
741 if (elem.IsLine())
742 {
743 // catch line
744 CPoint logical;
745 logical = ValuesToLogical(elem.center.X(), elem.center.Y());
746 CPoint p1 = GetPixelsFromLogical(logical);
747 logical = ValuesToLogical(elem.size.X(), elem.size.Y());
748 CPoint p2 = GetPixelsFromLogical(logical);
749 dist = DistFromLine(p1,p2,capture_PIXELS);
750 }
751 else if (elem.IsRectangle() || elem.IsEllipse() )
752 {
753 // catch rectangular
754 CPoint logical;
755 logical = ValuesToLogical(elem.GetXMin(), elem.GetYMin());
756 CPoint p1 = GetPixelsFromLogical(logical);
757 logical = ValuesToLogical(elem.GetXMax(), elem.GetYMin());
758 CPoint p2 = GetPixelsFromLogical(logical);
759 logical = ValuesToLogical(elem.GetXMax(), elem.GetYMax());
760 CPoint p3 = GetPixelsFromLogical(logical);
761 logical = ValuesToLogical(elem.GetXMin(), elem.GetYMax());
762 CPoint p4 = GetPixelsFromLogical(logical);
763
764 if( ( Minimum(p1.x,p3.x) <= capture_PIXELS.x) && ( capture_PIXELS.x <= Maximum(p1.x,p3.x) ) &&
765 ( Minimum(p1.y,p3.y) <= capture_PIXELS.y) && ( capture_PIXELS.y <= Maximum(p1.y,p3.y) ) )
766 {
767 // is IN the rectangle - some suitable constant value that allows to select nested elements above the main rectangle ( ?>0 )
768 dist = 0;
769 }
770 else
771 {
772 dist = Minimum( Minimum(DistFromLine(p1,p2,capture_PIXELS), DistFromLine(p2,p3,capture_PIXELS)),
773 Minimum(DistFromLine(p3,p4,capture_PIXELS), DistFromLine(p4,p1,capture_PIXELS)) );
774 }
775 }
776 else
777 {
778 ;
779 }
780 return dist;
781 }
782
DistFromLine(CPoint p1,CPoint p2,CPoint pmouse)783 int CDrawWindow2DView::DistFromLine(CPoint p1, CPoint p2, CPoint pmouse)
784 {
785 Vector2D vp1(p1.x,p1.y);
786 Vector2D vp2(p2.x,p2.y);
787 Vector2D vpm(pmouse.x, pmouse.y);
788 // double dist2 = MinDistLP(vp1,vp2,vpm);
789 double dist2;
790 Vector2D v = vp2-vp1;
791 Vector2D vlp = vpm-vp1;
792 double num = v*vlp;
793 double den = v*v;
794 if(num<=0.) dist2 = (vpm-vp1).Norm();
795 else if(num>=den) dist2 = (vpm-vp2).Norm();
796 else if(den>0.) dist2 = sqrt(vlp*vlp - num * num /den);
797 else dist2 = vlp.Norm();
798
799 return int(dist2+0.5);
800 }
801
802 #define ID_VIEW_ON_POPUP 1234
803 #define ID_MENU_PARENT_ON_POPUP 1235
804 #define ID_STATUSBAR_ON_POPUP 1236
805
806 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
807 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
808 // class CDrawWindow2DDlg: this is the dialog that nests the Graph (CMyView object), * 2012-12-12 +
809 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
810 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
811 // DrawWindow2DDlg-Dialogfeld
IMPLEMENT_DYNAMIC(CDrawWindow2DDlg,MyBaseDialogForView)812 IMPLEMENT_DYNAMIC(CDrawWindow2DDlg, MyBaseDialogForView)
813
814 CDrawWindow2DDlg::CDrawWindow2DDlg(CWnd* pParent /*=NULL*/)
815 : MyBaseDialogForView(pParent)
816 {
817 m_init_done = 0;
818 }
819
~CDrawWindow2DDlg()820 CDrawWindow2DDlg::~CDrawWindow2DDlg()
821 {
822 }
823
OnInitDialog()824 BOOL CDrawWindow2DDlg::OnInitDialog()
825 {
826 CDialog::OnInitDialog();
827
828 // create the View
829 CCreateContext cc;
830 cc.m_pNewViewClass = RUNTIME_CLASS(CDrawWindow2DView);
831 cc.m_pCurrentDoc = NULL;
832 cc.m_pNewDocTemplate = NULL;
833 cc.m_pLastView = NULL;
834 cc.m_pCurrentFrame = NULL;
835
836 m_pMyView = (CDrawWindow2DView*)CreateNewView(&cc, this, CRect(0, 0, 0, 0), ID_VIEW_ON_POPUP);
837 if (m_pMyView == NULL)
838 EndDialog(IDCANCEL);
839
840 CRect rect;
841 this->GetWindowRect(&rect);
842 rect.top = rect.bottom - 25;
843 int dbg = this->m_StatusBar.Create(WS_CHILD | WS_BORDER | WS_VISIBLE, rect, this, ID_STATUSBAR_ON_POPUP);
844
845 // place the View in the client rectangle
846 this->GetViewRect(GetView()->prevClientRect); // compute the current client rectangle of the nesting dialog
847 GetView()->prevClientRect.bottom -= 4;
848 GetView()->prevClientRect.right -=4;
849
850 PlaceElements();
851 GetView()->SetParentDlg(this);
852 m_init_done = 1;
853
854 // initial scene
855 pWCDI->RenderControlWindow(this); // Data is transfered to IO Blocks window
856 GetView()->SetInitialRange(); // initial range ( real coordinates ) is computed
857 GetView()->MatchLogicalPoints(); // logical points for the view are matched to the extend (pixels)
858 //
859
860 SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::OnInitDialog\n"));
861 this->UpdateWindow();
862 this->SetDisplayName(CString("IO Blocks"));
863 AllowRedraw();
864
865 return TRUE; // return TRUE unless you set the focus to a control
866 }
867
DestroyWindow()868 BOOL CDrawWindow2DDlg::DestroyWindow()
869 {
870 if (GetView())
871 GetView()->DestroyWindow();
872 return CDialog::DestroyWindow();
873 }
874
DoDataExchange(CDataExchange * pDX)875 void CDrawWindow2DDlg::DoDataExchange(CDataExchange* pDX)
876 {
877 CDialog::DoDataExchange(pDX);
878 }
879
BEGIN_MESSAGE_MAP(CDrawWindow2DDlg,MyBaseDialogForView)880 BEGIN_MESSAGE_MAP(CDrawWindow2DDlg, MyBaseDialogForView)
881 ON_WM_PAINT()
882 ON_WM_CLOSE()
883 ON_WM_SIZE()
884 ON_WM_GETMINMAXINFO()
885 ON_WM_MOVE()
886 ON_WM_SYSCOMMAND()
887 ON_WM_MOUSEWHEEL()
888 // CONTEXTMENU
889 ON_WM_CONTEXTMENU()
890 ON_COMMAND(ID_CM_ZOOMTOFULLRANGE, &CDrawWindow2DDlg::OnCMZoomToFullRange)
891 ON_COMMAND(ID_CM_EXPORTTOFILE, &CDrawWindow2DDlg::OnCMExportToFile)
892 ON_COMMAND(ID_CM_PRINTGRAPH, &CDrawWindow2DDlg::OnCMPrintGraph)
893 ON_COMMAND(ID_CM_INFOBLOCKVIEW, &CDrawWindow2DDlg::OnCMShowStatusInfo)
894 ON_COMMAND(ID_CM_SELECTOBJECT, &CDrawWindow2DDlg::OnCMSelectobject)
895 END_MESSAGE_MAP()
896
897 // ***********************************************
898 // WINDOW PROPERTIES & ADDITIONAL DISPLAY ELEMENTS
899 // ***********************************************
900 void CDrawWindow2DDlg::OnSize(UINT nType, int cx, int cy)
901 {
902 CDialog::OnSize(nType, cx, cy);
903
904 if (m_init_done)
905 {
906 PlaceElements(); // all rescaling (zoomfactors, shoenrange, etc.) is done
907 // placeelements calls Redraw()
908 CRect prevClientRect;
909 GetViewRect(prevClientRect); // get the current size ( before resize ) IN PIXELS
910 prevClientRect.bottom -=4;
911 prevClientRect.right -=4;
912 GetView()->prevClientRect = prevClientRect; // remember previous client
913 }
914 }
915
OnGetMinMaxInfo(MINMAXINFO * lpMMI)916 void CDrawWindow2DDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
917 {
918 // set the minimum tracking width
919 // and the minimum tracking height of the window
920 lpMMI->ptMinTrackSize.x = 150;
921 lpMMI->ptMinTrackSize.y = 100;
922 }
923
924
OnMove(int x,int y)925 void CDrawWindow2DDlg::OnMove(int x, int y)
926 {
927 CDialog::OnMove(x, y);
928 //if (m_init_done) PlaceElements();
929 }
930
OnClose()931 void CDrawWindow2DDlg::OnClose()
932 {
933 this->ShowWindow(SW_HIDE);
934 }
935
OnPaint()936 void CDrawWindow2DDlg::OnPaint()
937 {
938 SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::OnPaint\n"));
939 GetView()->UpdateWindow();
940 }
941
OnSysCommand(UINT nID,LPARAM lParam)942 void CDrawWindow2DDlg::OnSysCommand(UINT nID, LPARAM lParam) // catches selection in Menu
943 {
944 CDialog::OnSysCommand(nID, lParam);
945 }
946
OnMouseWheel(UINT nFlags,short zDelta,CPoint pt)947 BOOL CDrawWindow2DDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
948 {
949 return GetView()->OnMouseWheel(nFlags, zDelta, pt);
950 }
951
PreTranslateMessage(MSG * pMsg)952 BOOL CDrawWindow2DDlg::PreTranslateMessage(MSG* pMsg)
953 {
954 if(pMsg->message==WM_KEYDOWN)
955 {
956 int key = pMsg->wParam; // get the key-value
957 int nr_of_changes = pWCDI->CallCompFunction(31, key); // call the MBS-function
958 if (nr_of_changes>0) ForceUpdate(); // update if an MBS-element was changed
959 }
960 return MyBaseDialogForView::PreTranslateMessage(pMsg);
961 }
962
963 // force a full update ( call DrawSystem2D )
ForceUpdate()964 void CDrawWindow2DDlg::ForceUpdate()
965 {
966 // LOCK CALL OF DRAWING ROUTINE WHILE ARRAYS ARE UPDATED ( ACCESS TO ARRAYS NOT SAFE )
967 ForbidRedraw(); // manually block drawing of the dialog while the system is updated
968 pWCDI->RenderControlWindow(this);
969 // RELASE LOCK WHEN UPDATE IS DONE !
970 AllowRedraw();
971 if (m_init_done)
972 {
973 SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::ForceUpdate\n"));
974 RedrawWindow();
975 }
976 }
977
978 // ***************************************************************************************
979 // placement of the elements ( CMyView object & Dialog ) so the two dialogs stick together
980 // ***************************************************************************************
PlaceElements()981 void CDrawWindow2DDlg::PlaceElements()
982 {
983 // embed view on dialog
984 CRect viewrect;
985 this->GetViewRect(viewrect); // compute the current view rectangle
986 GetView()->MoveWindow(&viewrect); // does move window trigger a call of OnDraw here ? --> NO
987
988 // statusbar
989 CRect statusrect;
990 this->GetStatusRect(statusrect);
991 m_StatusBar.MoveWindow(&statusrect);
992
993 // two 70 point slots for coordinates at right end with 30 points additional border
994 int totalwidth = statusrect.Width();
995 int m_widths[4] = {0, totalwidth-170, totalwidth-100, totalwidth-30};
996 m_StatusBar.SetMinHeight(27);
997 m_StatusBar.SetParts(4, m_widths);
998
999 if(m_init_done)
1000 GetView()->Rescale(); // function that rescales the logical extents and shownrange such that
1001
1002
1003 RedrawWindow(0,0,RDW_FRAME|RDW_INVALIDATE);
1004
1005 // if(!DoNotRedraw()) // CATCH EXCEPTION - wincore.cpp l:248
1006 // {
1007 //// this line can be reached when OnDraw is in progress...
1008 // //SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::PlaceElement\n"));
1009 // //this->RedrawWindow(); // redraw Dialog
1010 // SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::PlaceElement II\n"));
1011 // GetView()->RedrawWindow(); // redraw View
1012 // }
1013 // else
1014 // {
1015 // int caught = 1;
1016 // }
1017 }
1018
1019 // ***************************************************************************************
1020 // context menu -
1021 // ***************************************************************************************
OnContextMenu(CWnd * pWnd,CPoint point)1022 void CDrawWindow2DDlg::OnContextMenu(CWnd* pWnd, CPoint point)
1023 {
1024 CMenu contextmenu;
1025
1026 contextmenu.CreatePopupMenu();
1027
1028 // when an element can be selected
1029 int nr_nearest_drawelem = this->GetView()->selected_object_buffer;
1030 int nr_nearest_mbselem = 0;
1031 mystr str;
1032 // identify the corresponding element number ( and type )
1033 if(nr_nearest_drawelem>0)
1034 {
1035 ControlWindowContext_::DrawComponent& elem = GetElement(nr_nearest_drawelem);
1036 if(elem.IsSelectableMBSElement())
1037 {
1038 // specific code for a selected element frame --> display "Edit Element X"
1039 str = mystr("Edit Element ") + mystr(elem.mbs_elnr);
1040 contextmenu.AppendMenu(MF_STRING, ID_CM_SELECTOBJECT, str.c_str());
1041 }
1042 else if(elem.IsSelectableConnectionLine())
1043 {
1044 str = mystr("Insert Construction Node") + mystr(elem.sub_elnr);
1045 contextmenu.AppendMenu(MF_STRING, ID_CM_SELECTOBJECT, str.c_str());
1046 }
1047 else if(elem.IsSelectableConstructionNode())
1048 {
1049 str = mystr("Delete Construction Node") + mystr(elem.sub_elnr);
1050 contextmenu.AppendMenu(MF_STRING, ID_CM_SELECTOBJECT, str.c_str());
1051 }
1052 contextmenu.AppendMenu(MF_SEPARATOR);
1053 }
1054
1055 contextmenu.AppendMenu(MF_STRING, ID_CM_ZOOMTOFULLRANGE, "Default Range");
1056 contextmenu.AppendMenu(MF_STRING, ID_CM_EXPORTTOFILE, "Save Screen");
1057 contextmenu.AppendMenu(MF_STRING, ID_CM_PRINTGRAPH, "Print Screen");
1058
1059 int nFlags = (MF_STRING | ( m_flag_statusinfo ? MF_CHECKED : MF_UNCHECKED ));
1060 contextmenu.AppendMenu(nFlags, ID_CM_INFOBLOCKVIEW, "Show Status Bar Information"); //(V) or (-)
1061
1062 contextmenu.TrackPopupMenu(TPM_LEFTALIGN| TPM_RIGHTBUTTON,point.x,point.y,this,NULL);
1063 }
1064
OnCMSelectobject()1065 void CDrawWindow2DDlg::OnCMSelectobject()
1066 {
1067 int nr_nearest_drawelem = this->GetView()->selected_object_buffer;
1068 int nr_nearest_mbselem = 0;
1069 // identify the corresponding element number ( and type )
1070 if(nr_nearest_drawelem>0)
1071 {
1072 ControlWindowContext_::DrawComponent& elem = GetElement(nr_nearest_drawelem);
1073 if(elem.IsSelectable())
1074 {
1075 if(elem.IsSelectableMBSElement())
1076 {
1077 // specific code for a selected element frame --> open edit element dialog
1078 int mbs_elem_nr = elem.mbs_elnr;
1079
1080 this->ShowWindow(SW_HIDE); //$AD 2013-07-01: WORKAROUND make sure that EditElementProperties Dialog is visible
1081 GetWCDDlg()->EditElementProperties(mbs_elem_nr, /*?*/1/*?*/);
1082 this->ForceUpdate(); //$ AD 2013-07-01: refresh 2D window after Prpoerties are changed
1083 this->ShowWindow(SW_SHOW); //$AD 2013-07-01: WORKAROUND make sure that EditElementProperties Dialog is visible
1084 }
1085 else if(elem.IsSelectableConnectionLine())
1086 {
1087 // specific code for a selected connection line --> new node in the middle of the line
1088 int mbs_elem_nr = elem.mbs_elnr;
1089 int list_idx = elem.sub_elnr % 65536; // last 16 bits of subelemnr code the array position to insert
1090 int inputnr = elem.sub_elnr / 65536; // first 16 bits of subelemnr code the associated input number
1091 Vector2D pos = 0.5 *( elem.P1()+elem.P2() ); // position in the middle of the line
1092
1093 GetWCDDlg()->GetWCDInterface()->InsertIOElemConNode(mbs_elem_nr, list_idx, inputnr, pos);
1094 this->ForceUpdate();
1095 }
1096 else if(elem.IsSelectableConstructionNode())
1097 {
1098 // specific code for a selected construction node --> delete from both lists
1099 int mbs_elem_nr = elem.mbs_elnr;
1100 int list_idx = elem.sub_elnr % 65536;
1101 int inputnr = elem.sub_elnr / 65536;
1102
1103 GetWCDDlg()->GetWCDInterface()->DeleteIOElemConNode(mbs_elem_nr,list_idx);
1104 this->ForceUpdate();
1105 }
1106 }
1107 }
1108 }
1109
OnCMZoomToFullRange()1110 void CDrawWindow2DDlg::OnCMZoomToFullRange()
1111 {
1112 GetView()->SetInitialRange(); // initial range ( real coordinates ) is computed
1113 GetView()->MatchLogicalPoints(); // logical points for the view are matched to the extend (pixels)
1114 SetCaller(mystr("REDRAW triggered by CDrawWindow2DDlg::OnCMZoomToFullRange\n"));
1115 GetView()->RedrawWindow();
1116 }
1117
OnCMExportToFile()1118 void CDrawWindow2DDlg::OnCMExportToFile()
1119 {
1120 // determine filename - TODO File Save Dialog
1121 mystr filename;
1122 CFileDialog fd(FALSE, "jpg", "C:\\temp\\IOBlocks.jpg", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "JPG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|BMP file (*.bmp)|*.bmp|EMF file (*.emf)|*.emf||");
1123 if(fd.DoModal() == IDOK)
1124 {
1125 CString fp = fd.GetFileName();
1126 CString fn = fd.GetPathName();
1127 CString fe = fd.GetFileExt();
1128 filename = mystr(fn);
1129
1130 int extension = 0;
1131 if (fe == CString("jpg")) extension = 1;
1132 if (fe == CString("png")) extension = 2;
1133 if (fe == CString("bmp")) extension = 4;
1134 if (fe == CString("emf")) extension = 8;
1135
1136 CString path_and_filename_noext = fn.Left(fn.GetLength()-4);
1137 if (extension&(4+2+1))
1138 {
1139 CRect rect; GetView()->GetClientRect(rect);
1140 GetView()->SaveAsBitmapGraphic(path_and_filename_noext, abs(rect.Width() ), abs(rect.Height()), extension&1, extension&2, extension&4);
1141 }
1142 if (extension&8)
1143 {
1144 GetView()->SaveAsVectorGraphic(path_and_filename_noext, extension&8);
1145 }
1146 }
1147 }
1148
OnCMPrintGraph()1149 void CDrawWindow2DDlg::OnCMPrintGraph()
1150 {
1151 Print();
1152 }
1153
OnCMShowStatusInfo()1154 void CDrawWindow2DDlg::OnCMShowStatusInfo()
1155 {
1156 if(m_flag_statusinfo)
1157 m_flag_statusinfo = 0; // change from show to dont show
1158 else
1159 m_flag_statusinfo = 1; // change from dont show to show
1160 UpdateData(FALSE); // keep the obsolete Checkbox in correct state ...
1161 }
1162
ComputeSplitPointPosition(ControlWindowContext_::DrawComponent & elem)1163 Vector2D CDrawWindow2DDlg::ComputeSplitPointPosition(ControlWindowContext_::DrawComponent& elem)
1164 {
1165 Vector2D newconnodepos = (elem.P1()+elem.P2())*0.5;
1166 return newconnodepos;
1167 }
1168
ComputeSplitPointListIndex(ControlWindowContext_::DrawComponent & elem)1169 int CDrawWindow2DDlg::ComputeSplitPointListIndex(ControlWindowContext_::DrawComponent& elem)
1170 {
1171 int newconnodelistindex = elem.sub_elnr;
1172 if ( newconnodelistindex < 0 ) newconnodelistindex = (-elem.sub_elnr)+1;
1173 return newconnodelistindex;
1174 }
1175