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