bool GraphicsWindow::ToolbarMouseMoved(int x, int y) { x += ((int)width/2); y += ((int)height/2); int nh = 0; bool withinToolbar = ToolbarDrawOrHitTest(x, y, false, &nh); if(!withinToolbar) nh = 0; if(nh != toolbarTooltipped) { // Don't let the tool tip move around if the mouse moves within the // same item. toolbarMouseX = x; toolbarMouseY = y; toolbarTooltipped = 0; } if(nh != toolbarHovered) { toolbarHovered = nh; SetTimerFor(1000); PaintGraphics(); } // So if we moved off the toolbar, then toolbarHovered is now equal to // zero, so it doesn't matter if the tool tip timer expires. And if // we moved from one item to another, we reset the timer, so also okay. return withinToolbar; }
void GraphicsWindow::MouseLeave(void) { // Un-hover everything when the mouse leaves our window, unless there's // currently a context menu shown. if(!context.active) { hover.Clear(); toolbarTooltipped = 0; toolbarHovered = 0; PaintGraphics(); } SS.extraLine.draw = false; }
void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) { // Get our initial orientation and translation. Quaternion quat0 = Quaternion::From(projRight, projUp); Vector offset0 = offset; // Make sure we take the shorter of the two possible paths. double mp = (quatf.Minus(quat0)).Magnitude(); double mm = (quatf.Plus(quat0)).Magnitude(); if(mp > mm) { quatf = quatf.ScaledBy(-1); mp = mm; } double mo = (offset0.Minus(offsetf)).Magnitude()*scale; // Animate transition, unless it's a tiny move. int32_t dt = (mp < 0.01 && mo < 10) ? (-20) : (int32_t)(100 + 1000*mp + 0.4*mo); // Don't ever animate for longer than 2000 ms; we can get absurdly // long translations (as measured in pixels) if the user zooms out, moves, // and then zooms in again. if(dt > 2000) dt = 2000; int64_t tn, t0 = GetMilliseconds(); double s = 0; Quaternion dq = quatf.Times(quat0.Inverse()); do { offset = (offset0.ScaledBy(1 - s)).Plus(offsetf.ScaledBy(s)); Quaternion quat = (dq.ToThe(s)).Times(quat0); quat = quat.WithMagnitude(1); projRight = quat.RotationU(); projUp = quat.RotationV(); PaintGraphics(); tn = GetMilliseconds(); s = (tn - t0)/((double)dt); } while((tn - t0) < dt); projRight = quatf.RotationU(); projUp = quatf.RotationV(); offset = offsetf; InvalidateGraphics(); // If the view screen is open, then we need to refresh it. SS.ScheduleShowTW(); }
void TextWindow::ScreenStepDimGo(int link, DWORD v) { hConstraint hc = SS.TW.shown.constraint; Constraint *c = SK.constraint.FindByIdNoOops(hc); if(c) { SS.UndoRemember(); double start = c->valA, finish = SS.TW.shown.dimFinish; int i, n = SS.TW.shown.dimSteps; for(i = 1; i <= n; i++) { c = SK.GetConstraint(hc); c->valA = start + ((finish - start)*i)/n; SS.MarkGroupDirty(c->group); SS.GenerateAll(); if(!SS.AllGroupsOkay()) { // Failed to solve, so quit break; } PaintGraphics(); } } InvalidateGraphics(); SS.TW.GoToScreen(SCREEN_LIST_OF_GROUPS); }
void GraphicsWindow::TimerCallback(void) { SS.GW.toolbarTooltipped = SS.GW.toolbarHovered; PaintGraphics(); }
LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_ERASEBKGND: break; case WM_SIZE: InvalidateRect(GraphicsWnd, NULL, false); break; case WM_PAINT: { // Actually paint the window, with gl. PaintGraphics(); // And make Windows happy. PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); break; } case WM_MOUSELEAVE: SS.GW.MouseLeave(); break; case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_MBUTTONDOWN: { int x = LOWORD(lParam); int y = HIWORD(lParam); // We need this in order to get the WM_MOUSELEAVE TRACKMOUSEEVENT tme; ZERO(&tme); tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; tme.hwndTrack = GraphicsWnd; TrackMouseEvent(&tme); // Convert to xy (vs. ij) style coordinates, with (0, 0) at center RECT r; GetClientRect(GraphicsWnd, &r); x = x - (r.right - r.left)/2; y = (r.bottom - r.top)/2 - y; LastMousePos.x = x; LastMousePos.y = y; if(msg == WM_LBUTTONDOWN) { SS.GW.MouseLeftDown(x, y); } else if(msg == WM_LBUTTONUP) { SS.GW.MouseLeftUp(x, y); } else if(msg == WM_LBUTTONDBLCLK) { SS.GW.MouseLeftDoubleClick(x, y); } else if(msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { SS.GW.MouseMiddleOrRightDown(x, y); } else if(msg == WM_RBUTTONUP) { SS.GW.MouseRightUp(x, y); } else if(msg == WM_MOUSEMOVE) { SS.GW.MouseMoved(x, y, !!(wParam & MK_LBUTTON), !!(wParam & MK_MBUTTON), !!(wParam & MK_RBUTTON), !!(wParam & MK_SHIFT), !!(wParam & MK_CONTROL)); } else { oops(); } break; } case WM_MOUSEWHEEL: MouseWheel(GET_WHEEL_DELTA_WPARAM(wParam)); break; case WM_COMMAND: { if(HIWORD(wParam) == 0) { int id = LOWORD(wParam); if((id >= RECENT_OPEN && id < (RECENT_OPEN + MAX_RECENT))) { SolveSpaceUI::MenuFile(id); break; } if((id >= RECENT_IMPORT && id < (RECENT_IMPORT + MAX_RECENT))) { Group::MenuGroup(id); break; } int i; for(i = 0; SS.GW.menu[i].level >= 0; i++) { if(id == SS.GW.menu[i].id) { (SS.GW.menu[i].fn)((GraphicsWindow::MenuId)id); break; } } if(SS.GW.menu[i].level < 0) oops(); } break; } case WM_CLOSE: case WM_DESTROY: SolveSpaceUI::MenuFile(GraphicsWindow::MNU_EXIT); return 1; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 1; }