gui_grapheditor.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958
  1. #ifndef _XBOX
  2. //*
  3. //****************************************************************
  4. #include "gui_grapheditor.h"
  5. #define BACKGROUND_COLOR 0xFFFFFFFF
  6. #define LINE_COLOR 0xFFEBEBEB
  7. #define TENLINE_COLOR 0xFFCDCDCD
  8. #define HUNDREDLINE_COLOR 0xFF999999
  9. #define AXIS_COLOR 0xFF000000
  10. #define FONT_COLOR 0xFF000000
  11. #define GRAPHBORDERS_COLOR 0xFF000000
  12. #define SMALLFONT_COLOR 0xFF000000
  13. #define MAXXPOS 8000.0f /* Самая большая позиция по оси X */
  14. #define PTSIZE 2 /* Размер рендерящихся вершин */
  15. #define PTHOTSPOT 6 /* Размер вершин для кликанья мышкой*/
  16. #define XOFFSET 30 /* Смещение всего графика по X */
  17. #define YOFFSET 10 /* Смещение всего графика по Y */
  18. #define MIN_DISTANCE_BETWEEN_POINTS 0.01f /* Максимально возможное расстояние между точками*/
  19. #define UNITS_IN_ONE_PIXEL 0.01f /* Сколько единиц в одном пикселе */
  20. char TmpChar8K[8192];
  21. GUIGraphEditor::GUIGraphEditor (GUIControl* pParent, int Left, int Top, int Width, int Height) : GUIControl (pParent)
  22. {
  23. mbBorned = false;
  24. SelectedLine = NULL;
  25. Lines = NEW GUILineList ();
  26. Mode = GEM_EDIT;
  27. CtrlState = true;
  28. NegativeValues = false;
  29. OffsetX = 10.0f;
  30. OffsetY = -YOFFSET;
  31. MouseButtonPressed = false;
  32. RMouseButtonPressed = false;
  33. HorizontalAxeDesc = "X";
  34. VerticalAxeDesc = "Y";
  35. LockXScale = false;
  36. LockYScale = false;
  37. pSmallFont = NEW GUIFont ("arialcyrsmall");
  38. if (pSmallFont) pSmallFont->SetSize(9.0f);
  39. pFont = NEW GUIFont ("arialcyrsmall");
  40. pRS = (IRender*)api->GetService("DX9Render");
  41. DrawRect.Left = Left;
  42. DrawRect.Top = Top;
  43. DrawRect.Width = Width;
  44. DrawRect.Height = Height;
  45. ClientRect = DrawRect;
  46. GridStepX = 1.0f;
  47. GridStepY = 1.0f;
  48. ScaleX = 4.5f;
  49. ScaleY = 4.5f;
  50. }
  51. GUIGraphEditor::~GUIGraphEditor ()
  52. {
  53. if (pFont) delete pFont;
  54. if (pSmallFont) delete pSmallFont;
  55. pFont = NULL;
  56. pSmallFont = NULL;
  57. delete Lines;
  58. }
  59. void GUIGraphEditor::Draw ()
  60. {
  61. if (Visible == false) return;
  62. GUIControl::Draw ();
  63. int Width = DrawRect.Width;
  64. int Height = DrawRect.Height;
  65. GUIRectangle rect = GetDrawRect ();
  66. this->ClientToScreen (rect);
  67. GUIHelper::DrawDownBorder(rect.x, rect.y , Width, Height);
  68. cliper.Push();
  69. GUIRectangle r;
  70. r = rect;
  71. r.x += 2;
  72. r.y += 2;
  73. r.w = Width - 4;
  74. r.h = Height - 4;
  75. cliper.SetRectangle(r);
  76. //render...
  77. DrawBackGround ();
  78. DrawLine ();
  79. cliper.Pop();
  80. if ((GetAsyncKeyState(VK_DELETE) < 0) && (!mbBorned))
  81. {
  82. GUIMessageBox* mb = GetMainControl()->Application->MessageBox("Clear graph ?", "Warning", GUIMB_YESNO);
  83. mb->OnOK = (CONTROL_EVENT)&GUIGraphEditor::OnClearYes;
  84. mb->OnCancel = (CONTROL_EVENT)&GUIGraphEditor::OnClearNo;
  85. mbBorned = true;
  86. }
  87. if ((GetAsyncKeyState(VK_CONTROL) < 0) && (GetAsyncKeyState(VK_ADD) < 0))
  88. {
  89. float ScaleFactor = (ScaleY / 450.0f);
  90. float Dist = 25.0;
  91. ScaleY += (Dist * ScaleFactor);
  92. }
  93. if ((GetAsyncKeyState(VK_CONTROL) < 0) && (GetAsyncKeyState(VK_SUBTRACT) < 0))
  94. {
  95. float ScaleFactor = (ScaleY / 450.0f);
  96. float Dist = -25.0;
  97. ScaleY += (Dist * ScaleFactor);
  98. if (ScaleY < 0.1) ScaleY = 0.1f;
  99. }
  100. }
  101. void _cdecl GUIGraphEditor::OnClearYes (GUIControl* sender)
  102. {
  103. mbBorned = false;
  104. for (int n = 0; n < Lines->GetCount(); n++)
  105. {
  106. GUIGraphLine* GraphLine = Lines->GetLine(n);
  107. GraphLine->Zero ();
  108. }
  109. }
  110. void _cdecl GUIGraphEditor::OnClearNo (GUIControl* sender)
  111. {
  112. mbBorned = false;
  113. }
  114. bool GUIGraphEditor::ProcessMessages (GUIMessage message, DWORD lparam, DWORD hparam)
  115. {
  116. if (!Visible) return false;
  117. // LockXScale = false;
  118. // LockYScale = false;
  119. GUIPoint cursor_pos;
  120. GUIHelper::ExtractCursorPos (message, lparam, hparam, cursor_pos);
  121. CtrlState = false;
  122. if (GetAsyncKeyState(VK_CONTROL) < 0) CtrlState = true;
  123. if (message == GUIMSG_LMB_DOWN)
  124. {
  125. OnMDown (message, cursor_pos);
  126. if (CtrlState)
  127. {
  128. if (SelectedLine)
  129. if (SelectedLine->SelectedPoint != -1)
  130. SelectedLine->Remove(SelectedLine->SelectedPoint);
  131. }
  132. }
  133. if (message == GUIMSG_RMB_DOWN)
  134. {
  135. RMouseButtonPressed = true;
  136. RBegMousePressed = cursor_pos;
  137. GetMainControl()->Application->GetCursor()->Push();
  138. GetMainControl()->Application->GetCursor()->SetCursor("hand");
  139. }
  140. /*
  141. if (message == GUIMSG_KEYPRESSED)
  142. {
  143. int Key = (int)lparam;
  144. if ((Key == VK_DELETE) && (GraphLine->SelectedPoint != -1))
  145. {
  146. if (GraphLine->GetCount() > 2)
  147. {
  148. GraphLine->Remove(GraphLine->SelectedPoint);
  149. GraphLine->SelectedPoint = -1;
  150. }
  151. }
  152. if ((Key == VK_ADD) && ((!LockXScale) && (!LockYScale)))
  153. {
  154. float ScaleFactor = (ScaleX / 450.0f);
  155. ScaleX -= ScaleFactor;
  156. ScaleY = ScaleX;
  157. }
  158. if ((Key == VK_SUBTRACT) && ((!LockXScale) && (!LockYScale)))
  159. {
  160. float ScaleFactor = (ScaleX / 450.0f);
  161. ScaleX += ScaleFactor;
  162. ScaleY = ScaleX;
  163. }
  164. if ((Key == 33) && (!LockYScale)) // Page up
  165. {
  166. float ScaleFactor = (ScaleY / 450.0f);
  167. ScaleY -= ScaleFactor;
  168. }
  169. if ((Key == 34) && (!LockYScale)) // Page down
  170. {
  171. float ScaleFactor = (ScaleY / 450.0f);
  172. ScaleY += ScaleFactor;
  173. }
  174. if ((Key == 36) && (!LockXScale)) // home
  175. {
  176. float ScaleFactor = (ScaleX / 450.0f);
  177. ScaleX -= ScaleFactor;
  178. }
  179. if ((Key == 35) && (!LockXScale)) // end
  180. {
  181. float ScaleFactor = (ScaleX / 450.0f);
  182. ScaleX += ScaleFactor;
  183. }
  184. }
  185. */
  186. return GUIControl::ProcessMessages (message, lparam, hparam);
  187. }
  188. void GUIGraphEditor::DrawBackGround ()
  189. {
  190. float fScalerY = 10.0f;
  191. float fScalerX = 10.0f;
  192. ClampScale ();
  193. pRS->Clear(0, NULL, CLEAR_STENCIL | CLEAR_TARGET | CLEAR_ZBUFFER, BACKGROUND_COLOR, 1.0f, 0);
  194. if (ScaleY > 2.0) fScalerY = 1.0f;
  195. if (ScaleX > 2.0) fScalerX = 1.0f;
  196. // 0.01 - в 100 пикселях одна единица графа
  197. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  198. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  199. GUIRectangle screenrect = DrawRect;
  200. ClientToScreen(screenrect);
  201. float Width = (float)DrawRect.w;
  202. float Height = (float)DrawRect.h;
  203. int StepXCount = (int)((Width * UnitsInOnePixelX) * fScalerX);
  204. int BigGrid = 0;
  205. if (ScaleX > 12) BigGrid = 1;
  206. if (ScaleX > 145) BigGrid = 2;
  207. bool ZeroLineIsDrawed = false;
  208. int ZeroLineY = -1;
  209. int ZeroLineHeight = -1;
  210. int ZeroLineX = -1;
  211. int StartFromX = (int)((-OffsetX * UnitsInOnePixelX) * fScalerX);
  212. for (int rx = StartFromX; rx <= StartFromX+StepXCount+1;rx++)
  213. {
  214. float x = (float)rx;
  215. if ((BigGrid == 1) && ((rx % 10) != 0)) continue;
  216. if ((BigGrid == 2) && ((rx % 100) != 0)) continue;
  217. int xpos = screenrect.x + (int)((x / UnitsInOnePixelX) / fScalerX);
  218. xpos += XOFFSET;
  219. DWORD clr = LINE_COLOR;
  220. if ((rx % 10) == 0) clr = TENLINE_COLOR;
  221. if ((rx % 100) == 0) clr = HUNDREDLINE_COLOR;
  222. if (x == 0) clr = AXIS_COLOR;
  223. xpos += (int)OffsetX;
  224. if (xpos < screenrect.x + XOFFSET) continue;
  225. if (clr == AXIS_COLOR)
  226. {
  227. ZeroLineIsDrawed = true;
  228. ZeroLineY = screenrect.y;
  229. ZeroLineHeight = (int)Height-YOFFSET;
  230. ZeroLineX = xpos+1;
  231. // GUIHelper::DrawVertLine(screenrect.y, (int)Height-YOFFSET, xpos+1, clr);
  232. } else
  233. {
  234. GUIHelper::DrawVertLine(screenrect.y, (int)Height-YOFFSET, xpos, clr);
  235. // Печатаем через 1
  236. if (!(rx & 1))
  237. {
  238. crt_snprintf (TmpChar8K, 7000, "%3.1f", (float)rx / fScalerX);
  239. int sf_width_div2 = pSmallFont->GetWidth(TmpChar8K) / 2;
  240. pSmallFont->Print(xpos-sf_width_div2, screenrect.y + (int)Height -YOFFSET, SMALLFONT_COLOR, TmpChar8K);
  241. }
  242. }
  243. }
  244. int StepYCount = 0;
  245. StepYCount = (int)((Height * UnitsInOnePixelY) * fScalerY);
  246. BigGrid = 0;
  247. if (ScaleY > 12) BigGrid = 1;
  248. if (ScaleY > 145) BigGrid = 2;
  249. int StartFromY = (int)((OffsetY * UnitsInOnePixelY) * fScalerY);
  250. for (int ry = StartFromY; ry <= StartFromY + StepYCount+1;ry++)
  251. {
  252. float y = (float)ry;
  253. if ((BigGrid == 1) && ((ry % 10) != 0)) continue;
  254. if ((BigGrid == 2) && ((ry % 100) != 0)) continue;
  255. DWORD clr = LINE_COLOR;
  256. if ((ry % 10) == 0) clr = TENLINE_COLOR;
  257. if ((ry % 100) == 0) clr = HUNDREDLINE_COLOR;
  258. if (y == 0) clr = AXIS_COLOR;
  259. int ypos = (screenrect.y+(int)Height) - (int)((y / UnitsInOnePixelY) / fScalerY);
  260. //ypos /= 100;
  261. ypos -= 4;
  262. ypos += (int)OffsetY;
  263. if (ypos > (screenrect.y+(int)Height)-YOFFSET) continue;
  264. GUIHelper::DrawHorizLine(screenrect.x+XOFFSET+1, (int)Width, ypos, clr);
  265. // Печатаем через 1
  266. if (!(ry & 1))
  267. {
  268. crt_snprintf (TmpChar8K, 7000, "%3.1f", (float)ry / fScalerY);
  269. int sf_width = pSmallFont->GetWidth(TmpChar8K);
  270. int sf_height_div2 = pSmallFont->GetHeight() / 2;
  271. pSmallFont->Print(screenrect.x+XOFFSET-sf_width-3, ypos-sf_height_div2, SMALLFONT_COLOR, TmpChar8K);
  272. if (clr == AXIS_COLOR)
  273. {
  274. pSmallFont->Print(screenrect.x+XOFFSET-sf_width-3+1, ypos-sf_height_div2, SMALLFONT_COLOR, TmpChar8K);
  275. }
  276. }
  277. if (clr == AXIS_COLOR)
  278. {
  279. GUIHelper::DrawHorizLine(screenrect.x+XOFFSET+1, (int)Width, ypos+1, clr);
  280. }
  281. }
  282. if (ZeroLineIsDrawed)
  283. {
  284. GUIHelper::DrawVertLine(ZeroLineY, ZeroLineHeight, ZeroLineX, AXIS_COLOR);
  285. GUIHelper::DrawVertLine(ZeroLineY, ZeroLineHeight, ZeroLineX+1, AXIS_COLOR);
  286. crt_snprintf (TmpChar8K, 7000, "0");
  287. int sf_width_div2 = pSmallFont->GetWidth(TmpChar8K) / 2;
  288. pSmallFont->Print(ZeroLineX-sf_width_div2, ZeroLineY + (int)Height -YOFFSET, SMALLFONT_COLOR, TmpChar8K);
  289. pSmallFont->Print(ZeroLineX-sf_width_div2+1, ZeroLineY + (int)Height -YOFFSET, SMALLFONT_COLOR, TmpChar8K);
  290. }
  291. GUIHelper::DrawVertLine(screenrect.y, (int)Height-YOFFSET, screenrect.x+XOFFSET, GRAPHBORDERS_COLOR);
  292. GUIHelper::DrawHorizLine(screenrect.x+XOFFSET, (int)Width, screenrect.y+(int)Height-YOFFSET, GRAPHBORDERS_COLOR);
  293. int HZ_Width = pFont->GetWidth(HorizontalAxeDesc.GetBuffer());
  294. int HZ_Height = pFont->GetHeight();
  295. pFont->Print(screenrect.x+XOFFSET+2, screenrect.y, FONT_COLOR, "%s", VerticalAxeDesc.GetBuffer());
  296. pFont->Print(screenrect.x+(int)Width-HZ_Width-2, screenrect.y+(int)Height-YOFFSET-HZ_Height, FONT_COLOR, "%s", HorizontalAxeDesc.GetBuffer());
  297. //pSmallFont
  298. /*
  299. int DigitSize = pFont->GetWidth("9");
  300. int FHd2= pFont->GetHeight() / 2;
  301. int FWd2= DigitSize;
  302. if (StepX >= 10) FWd2 += DigitSize;
  303. if (StepX >= 100) FWd2 += DigitSize;
  304. if (StepX >= 1000) FWd2 += DigitSize;
  305. int XBeginFrom = -OffsetX * UnitsInOnePixelX;
  306. if (RStepX <= 0) RStepX = 1;
  307. if (MaxY == 0) MaxY = 1;
  308. int DescWidth = pFont->GetWidth(HorizontalAxeDesc.GetBuffer());
  309. pFont->Print(screenrect.x+(int)Width-DescWidth-8, screenrect.y+(int)Height - (FHd2*4) - 4, FONT_COLOR, "%s", HorizontalAxeDesc.GetBuffer());
  310. pFont->Print(screenrect.x+(int)Width-FWd2-8, screenrect.y+(int)Height - (FHd2*2) - 4, FONT_COLOR, "%d", RStepX+XBeginFrom);
  311. int YBeginFrom = OffsetY * UnitsInOnePixelY;
  312. pFont->Print(screenrect.x+XOFFSET+3, screenrect.y + 4 , FONT_COLOR, "%s", VerticalAxeDesc.GetBuffer());
  313. pFont->Print(screenrect.x+XOFFSET+3, screenrect.y + 4 + (FHd2*2), FONT_COLOR, "%d", MaxY+YBeginFrom);
  314. pFont->Print(screenrect.x+XOFFSET+3, screenrect.y+(int)Height - (FHd2*2) - 4, FONT_COLOR, "%d", MinY+YBeginFrom);
  315. */
  316. }
  317. void GUIGraphEditor::DrawLine ()
  318. {
  319. GUIRectangle screenrect = DrawRect;
  320. ClientToScreen(screenrect);
  321. cliper.Push();
  322. GUIRectangle cliprect = screenrect;
  323. cliprect.x += XOFFSET;
  324. cliprect.w -= XOFFSET;
  325. cliprect.h -= YOFFSET;
  326. cliper.SetRectangle(cliprect);
  327. for (int n = 0; n < Lines->GetCount(); n++)
  328. {
  329. GUIGraphLine* GraphLine = Lines->GetLine(n);
  330. GraphLine->bNegative = NegativeValues;
  331. for (int i = 0; (i < GraphLine->GetCount()-1); i++)
  332. {
  333. Vector pt1 = GraphLine->GetPoint(i);
  334. Vector pt2 = GraphLine->GetPoint(i+1);
  335. if (!NegativeValues)
  336. {
  337. if (pt1.y < 0) pt1.y = 0;
  338. if (pt2.y < 0) pt2.y = 0;
  339. }
  340. TransformPoint (pt1, pt1);
  341. TransformPoint (pt2, pt2);
  342. if (pt1.x > screenrect.x + screenrect.w) break;
  343. if (pt2.x < screenrect.x + XOFFSET) continue;
  344. GUIHelper::Draw2DLine((int)pt1.x, (int)pt1.y , (int)pt2.x, (int)pt2.y, GraphLine->color);
  345. if (GraphLine->bActive) GUIHelper::Draw2DLine((int)pt1.x, (int)(pt1.y+1) , (int)pt2.x, (int)(pt2.y+1), GraphLine->color);
  346. }
  347. for ( i = 0; (i < GraphLine->GetCount()-1); i++)
  348. {
  349. Vector pt1 = GraphLine->GetPoint(i);
  350. if (!NegativeValues)
  351. if (pt1.y < 0) pt1.y = 0;
  352. TransformPoint (pt1, pt1);
  353. if (pt1.x > screenrect.x + screenrect.w) break;
  354. if (pt1.x < screenrect.x + XOFFSET) continue;
  355. bool bSel = false;
  356. if (GraphLine->SelectedPoint == i) bSel = true;
  357. DrawPoint (pt1, GraphLine->color, bSel);
  358. }
  359. }
  360. cliper.Pop();
  361. }
  362. void GUIGraphEditor::DrawPoint (const Vector& pos, DWORD color, bool Selected)
  363. {
  364. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE, (int)pos.y - PTSIZE, (int)pos.x + PTSIZE, (int)pos.y - PTSIZE, color);
  365. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE, (int)pos.y + PTSIZE, (int)pos.x + PTSIZE, (int)pos.y + PTSIZE, color);
  366. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE, (int)pos.y - PTSIZE, (int)pos.x - PTSIZE, (int)pos.y + PTSIZE, color);
  367. GUIHelper::Draw2DLine ((int)pos.x + PTSIZE, (int)pos.y - PTSIZE, (int)pos.x + PTSIZE, (int)pos.y + PTSIZE, color);
  368. if (!Selected) return;
  369. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE-1, (int)pos.y - PTSIZE-1, (int)pos.x + PTSIZE+1, (int)pos.y - PTSIZE-1, color);
  370. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE-1, (int)pos.y + PTSIZE+1, (int)pos.x + PTSIZE+1, (int)pos.y + PTSIZE+1, color);
  371. GUIHelper::Draw2DLine ((int)pos.x - PTSIZE-1, (int)pos.y - PTSIZE-1, (int)pos.x - PTSIZE-1, (int)pos.y + PTSIZE+1, color);
  372. GUIHelper::Draw2DLine ((int)pos.x + PTSIZE+1, (int)pos.y - PTSIZE-1, (int)pos.x + PTSIZE+1, (int)pos.y + PTSIZE+1, color);
  373. }
  374. void GUIGraphEditor::UnTransformPoint (const Vector& from, Vector& to)
  375. {
  376. Vector pt1 = from;
  377. GUIRectangle screenrect = DrawRect;
  378. ClientToScreen(screenrect);
  379. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  380. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  381. int Zero = screenrect.y + screenrect.h;
  382. Zero-=4;
  383. pt1.x -= OffsetX;
  384. pt1.y -= OffsetY;
  385. pt1.y = Zero + pt1.y;
  386. pt1.x -= XOFFSET;
  387. pt1.x -= screenrect.x;
  388. pt1.x *= UnitsInOnePixelX;
  389. pt1.y *= UnitsInOnePixelY;
  390. to = pt1;
  391. }
  392. void GUIGraphEditor::TransformPoint (const Vector& from, Vector& to)
  393. {
  394. Vector pt1 = from;
  395. GUIRectangle screenrect = DrawRect;
  396. ClientToScreen(screenrect);
  397. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  398. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  399. pt1.x /= UnitsInOnePixelX;
  400. pt1.y /= UnitsInOnePixelY;
  401. int Zero = screenrect.y + screenrect.h;
  402. Zero-=4;
  403. pt1.x += screenrect.x;
  404. pt1.x += XOFFSET;
  405. pt1.y = Zero - pt1.y;
  406. pt1.x += OffsetX;
  407. pt1.y += OffsetY;
  408. to = pt1;
  409. }
  410. void GUIGraphEditor::OnMDown (int MouseKey, const GUIPoint& pt)
  411. {
  412. Lines->SortByActive ();
  413. BegMousePressed = pt;
  414. MouseButtonPressed = true;
  415. if ((Mode == GEM_EDIT) || (Mode == GEM_MOVELINEY) || (Mode == GEM_SCALELINEX) || (Mode == GEM_SCALELINEY) || (Mode == GEM_MOVELINEX))
  416. {
  417. GUIRectangle screenrect = DrawRect;
  418. ClientToScreen(screenrect);
  419. Vector graphPt;
  420. ScreenToGraph (Vector ((float)pt.x, (float)(pt.y-(YOFFSET-3)), 0.0f), graphPt);
  421. for (int n = 0; n < Lines->GetCount(); n++)
  422. {
  423. GUIGraphLine* GraphLine = Lines->GetLine(n);
  424. GraphLine->LastMinimalPoint = -1;
  425. for (int i = 0; (i < GraphLine->GetCount()-1); i++)
  426. {
  427. Vector pt1 = GraphLine->GetPoint(i);
  428. if (pt1.x < graphPt.x)
  429. {
  430. GraphLine->LastMinimalPoint = i;
  431. }
  432. if (!NegativeValues)
  433. if (pt1.y < 0) pt1.y = 0;
  434. TransformPoint (pt1, pt1);
  435. if (pt1.x > screenrect.x + screenrect.w) break;
  436. if (pt1.x < screenrect.x + XOFFSET) continue;
  437. if ((pt.x > (pt1.x - PTHOTSPOT)) && (pt.x < (pt1.x + PTHOTSPOT)))
  438. {
  439. if ((pt.y > (pt1.y - PTHOTSPOT)) && (pt.y < (pt1.y + PTHOTSPOT)))
  440. {
  441. // Попали куда нужно...
  442. if (SelectedLine) SelectedLine->bActive = false;
  443. SelectedLine = GraphLine;
  444. SelectedLine->bActive = true;
  445. SelectedLine->SelectedPoint = i;
  446. Lines->SortByActive ();
  447. if (!NegativeValues)
  448. {
  449. Vector real_pt = GraphLine->GetPoint(i);
  450. if (real_pt.y < 0) real_pt.y = 0;
  451. GraphLine->Change(i, real_pt);
  452. }
  453. return;
  454. }
  455. }
  456. }
  457. }
  458. if ((SelectedLine) && (Mode == GEM_EDIT))
  459. {
  460. if (SelectedLine->LastMinimalPoint >= 0)
  461. {
  462. /*if (!NegativeValues)
  463. if (graphPt.y < 0.0f) graphPt.y = 0.0f;
  464. */
  465. if (!CtrlState)
  466. {
  467. SelectedLine->Insert((SelectedLine->LastMinimalPoint+1), graphPt);
  468. SelectedLine->SelectedPoint = (SelectedLine->LastMinimalPoint+1);
  469. } else
  470. {
  471. SelectedLine->SelectedPoint = SelectedLine->LastMinimalPoint;
  472. }
  473. } else
  474. {
  475. SelectedLine->SelectedPoint = -1;
  476. }
  477. }
  478. } // Mode == GEM_EDIT
  479. }
  480. void GUIGraphEditor::MouseUp (int button, const GUIPoint& pt)
  481. {
  482. if (button == GUIMSG_LMB_UP) MouseButtonPressed = false;
  483. if (button == GUIMSG_RMB_UP)
  484. {
  485. RMouseButtonPressed = false;
  486. GetMainControl()->Application->GetCursor()->Pop();
  487. }
  488. }
  489. void GUIGraphEditor::MouseMove (int button, const GUIPoint& pt)
  490. {
  491. if (MouseButtonPressed)
  492. {
  493. float dX = (float)(BegMousePressed.x - pt.x);
  494. float dY = (float)(BegMousePressed.y - pt.y);
  495. // Режим редактирования...
  496. if ((Mode == GEM_EDIT) && (SelectedLine))
  497. {
  498. if (SelectedLine->SelectedPoint == -1) return;
  499. dX *= UNITS_IN_ONE_PIXEL;
  500. dY *= UNITS_IN_ONE_PIXEL;
  501. dX *= ScaleX;
  502. dY *= ScaleY;
  503. Vector cpos = SelectedLine->GetPoint(SelectedLine->SelectedPoint);
  504. Vector savedpos = cpos;
  505. if (SelectedLine->SelectedPoint > 0) cpos.x -= dX;
  506. cpos.y += dY;
  507. if (cpos.x < 0) cpos.x = 0;
  508. if (cpos.x > MAXXPOS) cpos.x = MAXXPOS;
  509. if (SelectedLine->SelectedPoint >= 1)
  510. {
  511. Vector minpos = SelectedLine->GetPoint((SelectedLine->SelectedPoint-1));
  512. if (cpos.x < (minpos.x + MIN_DISTANCE_BETWEEN_POINTS))
  513. {
  514. cpos.x = (minpos.x + MIN_DISTANCE_BETWEEN_POINTS);
  515. }
  516. }
  517. int LastPoint = (SelectedLine->GetCount()-1);
  518. if (SelectedLine->SelectedPoint < LastPoint)
  519. {
  520. Vector maxpos = SelectedLine->GetPoint((SelectedLine->SelectedPoint+1));
  521. if (cpos.x > (maxpos.x - MIN_DISTANCE_BETWEEN_POINTS))
  522. {
  523. cpos.x = (maxpos.x - MIN_DISTANCE_BETWEEN_POINTS);
  524. }
  525. }
  526. /*
  527. if (!NegativeValues)
  528. if (cpos.y < 0) cpos.y = 0;
  529. */
  530. SelectedLine->Change(SelectedLine->SelectedPoint, cpos);
  531. }
  532. if (Mode == GEM_SCALE)
  533. {
  534. float ScaleFactorX = (ScaleX / 450.0f);
  535. float ScaleFactorY = (ScaleY / 450.0f);
  536. float ScaleFactor = ScaleFactorX+ScaleFactorY;
  537. float Dist = dX + dY;
  538. //Dist *= 0.05f;
  539. ScaleX += (Dist * ScaleFactor);
  540. ScaleY += (Dist * ScaleFactor);
  541. }
  542. if (Mode == GEM_SCALEX)
  543. {
  544. float ScaleFactor = (ScaleX / 450.0f);
  545. float Dist = dX + dY;
  546. //Dist *= 0.05f;
  547. ScaleX += (Dist * ScaleFactor);
  548. }
  549. if (Mode == GEM_SCALEY)
  550. {
  551. float ScaleFactor = (ScaleY / 450.0f);
  552. float Dist = dX + dY;
  553. //Dist *= 0.05f;
  554. ScaleY += (Dist * ScaleFactor);
  555. }
  556. if ((Mode == GEM_MOVELINEY) && (SelectedLine))
  557. {
  558. for (int n = 0; n < SelectedLine->GetCount(); n++)
  559. {
  560. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  561. Vector pt = SelectedLine->GetPoint(n);
  562. pt.y += (dY * UnitsInOnePixelY);
  563. SelectedLine->Change(n, pt);
  564. }
  565. }
  566. if ((Mode == GEM_MOVELINEX) && (SelectedLine))
  567. {
  568. for (int n = 1; n < (SelectedLine->GetCount()-1); n++)
  569. {
  570. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  571. Vector pt = SelectedLine->GetPoint(n);
  572. pt.x -= (dX * UnitsInOnePixelX);
  573. Vector pt_prev = SelectedLine->GetPoint(n-1);
  574. if ((pt_prev.x + MIN_DISTANCE_BETWEEN_POINTS) > pt.x)
  575. {
  576. pt.x = (pt_prev.x + MIN_DISTANCE_BETWEEN_POINTS);
  577. }
  578. SelectedLine->Change(n, pt);
  579. }
  580. }
  581. if ((Mode == GEM_SCALELINEY) && (SelectedLine))
  582. {
  583. float MaxY = -99999999.0f;
  584. float MinY = 99999999.0f;
  585. for (int n = 0; n < SelectedLine->GetCount(); n++)
  586. {
  587. Vector pt = SelectedLine->GetPoint(n);
  588. if (pt.y < MinY) MinY = pt.y;
  589. if (pt.y > MaxY) MaxY = pt.y;
  590. }
  591. float MidY = MinY + ((MaxY - MinY) * 0.5f);
  592. for ( n = 0; n < SelectedLine->GetCount(); n++)
  593. {
  594. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  595. Vector pt = SelectedLine->GetPoint(n);
  596. float ScaleK = 0.98f;
  597. if (dX < 0) ScaleK = 1.02f;
  598. pt.y -= MidY;
  599. pt.y *= ScaleK;
  600. pt.y += MidY;
  601. SelectedLine->Change(n, pt);
  602. }
  603. }
  604. if ((Mode == GEM_SCALELINEX) && (SelectedLine))
  605. {
  606. /*
  607. float MaxX = -99999999.0f;
  608. float MinX = 99999999.0f;
  609. for (int n = 1; n < SelectedLine->GetCount()-1; n++)
  610. {
  611. Vector pt = SelectedLine->GetPoint(n);
  612. if (pt.x < MinX) MinX = pt.x;
  613. if (pt.x > MaxX) MaxX = pt.x;
  614. }
  615. float MidX = MinX + ((MaxX - MinX) * 0.5f);
  616. */
  617. for (int n = 1; n < SelectedLine->GetCount()-1; n++)
  618. {
  619. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  620. Vector pt = SelectedLine->GetPoint(n);
  621. float ScaleK = 0.98f;
  622. if (dX < 0) ScaleK = 1.02f;
  623. //pt.x -= MidX;
  624. pt.x *= ScaleK;
  625. //pt.x += MidX;
  626. Vector pt_prev = SelectedLine->GetPoint(n-1);
  627. if ((pt_prev.x + MIN_DISTANCE_BETWEEN_POINTS) > pt.x)
  628. {
  629. pt.x = (pt_prev.x + MIN_DISTANCE_BETWEEN_POINTS);
  630. }
  631. SelectedLine->Change(n, pt);
  632. }
  633. }
  634. BegMousePressed = pt;
  635. }
  636. if (RMouseButtonPressed)
  637. {
  638. float dX = (float)(RBegMousePressed.x - pt.x);
  639. float dY = (float)(RBegMousePressed.y - pt.y);
  640. RBegMousePressed = pt;
  641. OffsetX -= dX;
  642. OffsetY -= dY;
  643. if (OffsetX > 32) OffsetX = 32;
  644. }
  645. }
  646. void GUIGraphEditor::ScreenToGraph (const Vector& fromr, Vector& to)
  647. {
  648. Vector from = fromr;
  649. GUIRectangle screenrect = DrawRect;
  650. ClientToScreen(screenrect);
  651. float realX = from.x - screenrect.x;
  652. float realY = from.y - screenrect.y;
  653. realY = screenrect.h - realY;
  654. realX -= XOFFSET;
  655. realY -= YOFFSET;
  656. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  657. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  658. realX -= OffsetX;
  659. realY += OffsetY;
  660. realX *= UnitsInOnePixelX;
  661. realY *= UnitsInOnePixelY;
  662. to.x = realX;
  663. to.y = realY;
  664. to.z = 0.0f;
  665. }
  666. void GUIGraphEditor::FitViewWidth (float Min, float Max)
  667. {
  668. float Interval = fabsf(Max - Min);
  669. GUIRectangle d_rect = GetDrawRect();
  670. float UnitsInGraph = ((d_rect.w-(XOFFSET*2)) * UNITS_IN_ONE_PIXEL);
  671. ScaleX = Interval / UnitsInGraph;
  672. ClampScale ();
  673. float UnitsInOnePixelX = UNITS_IN_ONE_PIXEL * ScaleX;
  674. OffsetX = Min / UnitsInOnePixelX;
  675. }
  676. void GUIGraphEditor::FitViewHeight (float Min, float Max)
  677. {
  678. if (Min < 0.0f && Max < 0.0f) Max = 0.0f;
  679. if (Min > 0.0f && Max > 0.0f) Min = 0.0f;
  680. float Interval = fabsf(Max - Min);
  681. GUIRectangle d_rect = GetDrawRect();
  682. float UnitsInGraph = ((d_rect.h-(YOFFSET*2)) * UNITS_IN_ONE_PIXEL);
  683. ScaleY = Interval / UnitsInGraph;
  684. ClampScale ();
  685. float UnitsInOnePixelY = UNITS_IN_ONE_PIXEL * ScaleY;
  686. OffsetY = (Min-(UnitsInOnePixelY*10)) / UnitsInOnePixelY;
  687. //(UnitsInOnePixelY/ 10.0f );
  688. }
  689. float GUIGraphEditor::GetMaxValueY ()
  690. {
  691. float MaxY = -9999999999.0f;
  692. for (int n = 0; n < Lines->GetCount(); n++)
  693. {
  694. GUIGraphLine* GraphLine = Lines->GetLine(n);
  695. for (int i = 0; (i < GraphLine->GetCount()-1); i++)
  696. {
  697. Vector pt1 = GraphLine->GetPoint(i);
  698. if (pt1.y > MaxY) MaxY = pt1.y;
  699. }
  700. }
  701. return MaxY;
  702. }
  703. float GUIGraphEditor::GetMinValueY ()
  704. {
  705. float MinY = 9999999999.0f;
  706. for (int n = 0; n < Lines->GetCount(); n++)
  707. {
  708. GUIGraphLine* GraphLine = Lines->GetLine(n);
  709. for (int i = 0; (i < GraphLine->GetCount()-1); i++)
  710. {
  711. Vector pt1 = GraphLine->GetPoint(i);
  712. if (pt1.y < MinY) MinY = pt1.y;
  713. }
  714. }
  715. return MinY;
  716. }
  717. void GUIGraphEditor::ClampScale ()
  718. {
  719. if (ScaleX < 0.009f) ScaleX = 0.009f;
  720. if (ScaleY < 0.009f) ScaleY = 0.009f;
  721. if (ScaleX > 1345.0f) ScaleX = 1345.0f;
  722. if (ScaleY > 1345.0f) ScaleY = 1345.0f;
  723. }
  724. #endif