bool Window::onProcessMessage(Message* msg) { switch (msg->type()) { case kOpenMessage: m_killer = NULL; break; case kCloseMessage: saveLayout(); break; case kMouseDownMessage: { if (!m_isMoveable) break; clickedMousePos = static_cast<MouseMessage*>(msg)->position(); m_hitTest = hitTest(clickedMousePos); if (m_hitTest != HitTestNowhere && m_hitTest != HitTestClient) { if (clickedWindowPos == NULL) clickedWindowPos = new gfx::Rect(getBounds()); else *clickedWindowPos = getBounds(); captureMouse(); return true; } else break; } case kMouseUpMessage: if (hasCapture()) { releaseMouse(); jmouse_set_cursor(kArrowCursor); if (clickedWindowPos != NULL) { delete clickedWindowPos; clickedWindowPos = NULL; } m_hitTest = HitTestNowhere; return true; } break; case kMouseMoveMessage: if (!m_isMoveable) break; // Does it have the mouse captured? if (hasCapture()) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); // Reposition/resize if (m_hitTest == HitTestCaption) { int x = clickedWindowPos->x + (mousePos.x - clickedMousePos.x); int y = clickedWindowPos->y + (mousePos.y - clickedMousePos.y); moveWindow(gfx::Rect(x, y, getBounds().w, getBounds().h), true); } else { int x, y, w, h; w = clickedWindowPos->w; h = clickedWindowPos->h; bool hitLeft = (m_hitTest == HitTestBorderNW || m_hitTest == HitTestBorderW || m_hitTest == HitTestBorderSW); bool hitTop = (m_hitTest == HitTestBorderNW || m_hitTest == HitTestBorderN || m_hitTest == HitTestBorderNE); bool hitRight = (m_hitTest == HitTestBorderNE || m_hitTest == HitTestBorderE || m_hitTest == HitTestBorderSE); bool hitBottom = (m_hitTest == HitTestBorderSW || m_hitTest == HitTestBorderS || m_hitTest == HitTestBorderSE); if (hitLeft) { w += clickedMousePos.x - mousePos.x; } else if (hitRight) { w += mousePos.x - clickedMousePos.x; } if (hitTop) { h += (clickedMousePos.y - mousePos.y); } else if (hitBottom) { h += (mousePos.y - clickedMousePos.y); } limitSize(&w, &h); if ((getBounds().w != w) || (getBounds().h != h)) { if (hitLeft) x = clickedWindowPos->x - (w - clickedWindowPos->w); else x = getBounds().x; if (hitTop) y = clickedWindowPos->y - (h - clickedWindowPos->h); else y = getBounds().y; moveWindow(gfx::Rect(x, y, w, h), false); invalidate(); } } } break; case kSetCursorMessage: if (m_isMoveable) { gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position(); HitTest ht = hitTest(mousePos); CursorType cursor = kArrowCursor; switch (ht) { case HitTestCaption: cursor = kArrowCursor; break; case HitTestBorderNW: cursor = kSizeTLCursor; break; case HitTestBorderW: cursor = kSizeLCursor; break; case HitTestBorderSW: cursor = kSizeBLCursor; break; case HitTestBorderNE: cursor = kSizeTRCursor; break; case HitTestBorderE: cursor = kSizeRCursor; break; case HitTestBorderSE: cursor = kSizeBRCursor; break; case HitTestBorderN: cursor = kSizeTCursor; break; case HitTestBorderS: cursor = kSizeBCursor; break; } jmouse_set_cursor(cursor); return true; } break; } return Widget::onProcessMessage(msg); }
// Получение геометрии индикации масштабирования шкалы QRect *QAxisZoomSvc::axisZoomRect(QPoint evpos,int ax) { // получаем указатель на график QwtPlot *plt = zoom->plot(); // определяем (для удобства) геометрию QRect gc = plt->canvas()->geometry(); // канвы графика QRect gw = plt->axisWidget(ax)->geometry(); // и виджета шкалы // определяем текущее положение курсора относительно канвы графика int x = evpos.x() + gw.x() - gc.x() - scb_pxl; int y = evpos.y() + gw.y() - gc.y() - scb_pyt; // запоминаем (для удобства) int wax = gw.width(); // ширину виджета шкалы int hax = gw.height(); // и высоту // читаем режим масштабирования QwtChartZoom::QConvType ct = zoom->regim(); // объявляем положение левого верхнего угла, int wl,wt,ww,wh; // ширину и высоту // если масштабируется горизонтальная шкала, то if (ax == QwtPlot::xBottom || ax == QwtPlot::xTop) { // если изменяется правая граница, то if (ct == QwtChartZoom::ctAxisHR) { // ограничение на положение курсора слева int mn = floor((float)(scb_pw/16)); // если курсор слишком близко к левой границе, то if (x < mn) x = mn; // ширина прямоугольника ww = floor((float)(x * scb_pw / scp_x)); // применяем ограничения ww = limitSize(ww,scb_pw); // левый отступ прямоугольника wl = sab_pxl; } else // иначе (изменяется левая граница) { // ограничение на положение курсора справа int mx = floor((float)(15*scb_pw/16)); // если курсор слишком близко к правой границе, то if (x > mx) x = mx; // ширина прямоугольника ww = floor((float)((scb_pw - x) * scb_pw / (scb_pw - scp_x))); // применяем ограничения ww = limitSize(ww,scb_pw); // левый отступ прямоугольника wl = sab_pxl + scb_pw - ww; } // высота прямоугольника wh = 4; // верхний отступ прямоугольника wt = 10; // для нижней шкалы // если не помещается на шкале, корректируем if (wt + wh > hax) wt = hax - wh; // для верхней шкалы симметрично if (ax == QwtPlot::xTop) wt = hax - wt - wh; } else // иначе (масштабируется вертикальная шкала) { // если изменяется нижняя граница, то if (ct == QwtChartZoom::ctAxisVB) { // ограничение на положение курсора сверху int mn = floor((float)(scb_ph/16)); // если курсор слишком близко к верхней границе, то if (y < mn) y = mn; // высота прямоугольника wh = floor((float)(y * scb_ph / scp_y)); // применяем ограничения wh = limitSize(wh,scb_ph); // верхний отступ прямоугольника wt = sab_pyt; } else // иначе (изменяется верхняя граница) { // ограничение на положение курсора снизу int mx = floor((float)(15*scb_ph/16)); // если курсор слишком близко к нижней границе, то if (y > mx) y = mx; // высота прямоугольника wh = floor((float)((scb_ph - y) * scb_ph / (scb_ph - scp_y))); // применяем ограничения wh = limitSize(wh,scb_ph); // верхний отступ прямоугольника = смещению курсора wt = sab_pyt + scb_ph - wh; } // ширина прямоугольника ww = 4; // верхний отступ прямоугольника wl = 10; // для правой шкалы // если не помещается на шкале, корректируем if (wl + ww > wax) wl = wax - ww; // для левой шкалы симметрично if (ax == QwtPlot::yLeft) wl = wax - wl - ww; } // создаем и возвращаем геометрию виджета // с вычисленными размерами return new QRect(wl,wt,ww,wh); }