Changeset 109 for trunk/src


Ignore:
Timestamp:
Aug 13, 2009, 8:20:25 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

gui: Added modality implementation.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/gui/kernel/qapplication_pm.cpp

    r108 r109  
    104104extern QCursor *qt_grab_cursor();
    105105
     106extern void qt_WinQueryClipRegionOrRect(HWND hwnd, HRGN hrgn); // qwidget_pm.cpp
     107
    106108MRESULT EXPENTRY QtWndProc(HWND, ULONG, MPARAM, MPARAM);
    107109
     
    125127#endif
    126128    bool        translatePaintEvent(const QMSG &qmsg);
    127 //  bool        translateConfigEvent(const MSG &msg);
    128 //  bool        translateCloseEvent(const MSG &msg);
     129//  bool        translateConfigEvent(const QMSG &msg);
     130    bool        translateCloseEvent(const QMSG &qmsg);
    129131//  void        repolishStyle(QStyle &style);
    130132//  inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); }
     
    333335void  QApplication::setCursorFlashTime(int msecs)
    334336{
    335     // @todo implement
    336 }
    337 
     337    WinSetSysValue(HWND_DESKTOP, SV_CURSORRATE, msecs / 2);
     338    QApplicationPrivate::cursor_flash_time = msecs;
     339}
    338340
    339341int QApplication::cursorFlashTime()
    340342{
    341     // @todo implement
     343    int blink = (int)WinQuerySysValue(HWND_DESKTOP, SV_CURSORRATE);
     344    if (!blink)
     345        return QApplicationPrivate::cursor_flash_time;
     346    if (blink > 0)
     347        return 2 * blink;
    342348    return 0;
    343349}
     
    345351void QApplication::setDoubleClickInterval(int ms)
    346352{
    347     // @todo implement
     353    WinSetSysValue(HWND_DESKTOP, SV_DBLCLKTIME, ms);
     354    QApplicationPrivate::mouse_double_click_time = ms;
    348355}
    349356
    350357int QApplication::doubleClickInterval()
    351358{
    352     // @todo implement
    353     return 0;
    354 }
    355 
     359    int ms = (int) WinQuerySysValue(HWND_DESKTOP, SV_DBLCLKTIME);
     360    if (ms != 0)
     361        return ms;
     362    return QApplicationPrivate::mouse_double_click_time;
     363}
    356364
    357365void QApplication::setKeyboardInputInterval(int ms)
    358366{
    359     // @todo implement
     367    QApplicationPrivate::keyboard_input_time = ms;
    360368}
    361369
    362370int QApplication::keyboardInputInterval()
    363371{
    364     // @todo implement
    365     return 0;
     372    // FIXME: get from the system
     373    return QApplicationPrivate::keyboard_input_time;
    366374}
    367375
     
    369377void QApplication::setWheelScrollLines(int n)
    370378{
    371     // @todo implement
     379    QApplicationPrivate::wheel_scroll_lines = n;
    372380}
    373381
    374382int QApplication::wheelScrollLines()
    375383{
    376     // @todo implement
    377     return 0;
     384    return QApplicationPrivate::wheel_scroll_lines;
    378385}
    379386#endif //QT_NO_WHEELEVENT
     
    392399void QApplication::beep()
    393400{
    394     // @todo implement
     401    WinAlarm(HWND_DESKTOP, WA_WARNING);
    395402}
    396403
     
    431438  Main event loop
    432439 *****************************************************************************/
     440
     441// sent to hwnd that has been entered to by a mouse pointer.
     442// FID_CLIENT also receives enter messages of its WC_FRAME.
     443// mp1 = hwnd that is entered, mp2 = hwnd that is left
     444#define WM_U_MOUSEENTER 0x41E
     445// sent to hwnd that has been left by a mouse pointer.
     446// FID_CLIENT also receives leave messages of its WC_FRAME.
     447// mp1 = hwnd that is left, mp2 = hwnd that is entered
     448#define WM_U_MOUSELEAVE 0x41F
     449
     450// some undocumented system values
     451#define SV_WORKAREA_YTOP    51
     452#define SV_WORKAREA_YBOTTOM 52
     453#define SV_WORKAREA_XRIGHT  53
     454#define SV_WORKAREA_XLEFT   54
    433455
    434456// QtWndProc() receives all messages from the main event loop
     
    537559            case WM_SHOW: {
    538560                // @todo there is some more processing in Qt4, see
    539                 // WM_SHOWWINDOW in Win32 sources
     561                // WM_SHOWWINDOW in qapplication_win.cpp
    540562                if (!SHORT1FROMMP(mp1) && autoCaptureWnd == widget->internalWinId())
    541563                    releaseAutoCapture();
     564                break;
     565            }
     566
     567            case WM_CLOSE: { // close window
     568                widget->translateCloseEvent(qmsg);
     569                return (MRESULT)TRUE;
     570            }
     571
     572            case WM_DESTROY: { // destroy window
     573                if (hwnd == curWin) {
     574                    QWidget *enter = QWidget::mouseGrabber();
     575                    if (enter == widget)
     576                        enter = 0;
     577                    QApplicationPrivate::dispatchEnterLeave(enter, widget);
     578                    curWin = enter ? enter->effectiveWinId() : 0;
     579                    qt_last_mouse_receiver = enter;
     580                }
     581                if (widget == popupButtonFocus)
     582                    popupButtonFocus = 0;
    542583                break;
    543584            }
     
    564605#endif
    565606
     607            case WM_U_MOUSELEAVE: {
     608                // We receive a mouse leave for curWin, meaning
     609                // the mouse was moved outside our widgets
     610                if (widget->internalWinId() == curWin) {
     611                    bool dispatch = !widget->underMouse();
     612                    // hasMouse is updated when dispatching enter/leave,
     613                    // so test if it is actually up-to-date
     614                    if (!dispatch) {
     615                        QRect geom = widget->geometry();
     616                        if (widget->parentWidget() && !widget->isWindow()) {
     617                            QPoint gp = widget->parentWidget()->mapToGlobal(widget->pos());
     618                            geom.setX(gp.x());
     619                            geom.setY(gp.y());
     620                        }
     621                        QPoint cpos = QCursor::pos();
     622                        dispatch = !geom.contains(cpos);
     623                        if ( !dispatch && !QWidget::mouseGrabber()) {
     624                            QWidget *hittest = QApplication::widgetAt(cpos);
     625                            dispatch = !hittest || hittest->internalWinId() != curWin;
     626                        }
     627                        if (!dispatch) {
     628                            HPS hps = qt_display_ps();
     629                            HRGN hrgn = GpiCreateRegion(hps, 0, NULL);
     630                            qt_WinQueryClipRegionOrRect(hwnd, hrgn);
     631                            QPoint lcpos = widget->mapFromGlobal(cpos);
     632                            // flip y coordinate
     633                            POINTL pt = { lcpos.x(), widget->height() - (lcpos.y() + 1) };
     634                            dispatch = !GpiPtInRegion(hps, hrgn, &pt);
     635                            GpiDestroyRegion(hps, hrgn);
     636                        }
     637                    }
     638                    if (dispatch) {
     639                        if (qt_last_mouse_receiver && !qt_last_mouse_receiver->internalWinId())
     640                            QApplicationPrivate::dispatchEnterLeave(0, qt_last_mouse_receiver);
     641                        else
     642                            QApplicationPrivate::dispatchEnterLeave(0, QWidget::find((WId)curWin));
     643                        curWin = 0;
     644                        qt_last_mouse_receiver = 0;
     645                    }
     646                }
     647                break;
     648            }
     649
    566650            default:
    567651                break;
     
    620704bool QApplicationPrivate::modalState()
    621705{
    622     // @todo implement
    623     return false;
     706    return app_do_modal;
    624707}
    625708
    626709void QApplicationPrivate::enterModal_sys(QWidget *widget)
    627710{
    628     // @todo implement
     711    if (!qt_modal_stack)
     712        qt_modal_stack = new QWidgetList;
     713
     714    releaseAutoCapture();
     715    QWidget *leave = qt_last_mouse_receiver;
     716    if (!leave)
     717        leave = QWidget::find(curWin);
     718    QApplicationPrivate::dispatchEnterLeave(0, leave);
     719    qt_modal_stack->insert(0, widget);
     720    app_do_modal = true;
     721    curWin = 0;
     722    qt_last_mouse_receiver = 0;
     723    ignoreNextMouseReleaseEvent = false;
    629724}
    630725
    631726void QApplicationPrivate::leaveModal_sys(QWidget *widget)
    632727{
    633     // @todo implement
    634 }
    635 
    636 bool qt_try_modal(QWidget *widget, QMSG *qmsg, MRESULT& rc)
    637 {
    638     // @todo implement
    639     return false;
     728    if (qt_modal_stack && qt_modal_stack->removeAll(widget)) {
     729        if (qt_modal_stack->isEmpty()) {
     730            delete qt_modal_stack;
     731            qt_modal_stack = 0;
     732            QPoint p(QCursor::pos());
     733            app_do_modal = false; // necessary, we may get recursively into qt_try_modal below
     734            QWidget* w = QApplication::widgetAt(p.x(), p.y());
     735            QWidget *leave = qt_last_mouse_receiver;
     736            if (!leave)
     737                leave = QWidget::find(curWin);
     738            if (QWidget *grabber = QWidget::mouseGrabber()) {
     739                w = grabber;
     740                if (leave == w)
     741                    leave = 0;
     742            }
     743            QApplicationPrivate::dispatchEnterLeave(w, leave); // send synthetic enter event
     744            curWin = w ? w->effectiveWinId() : 0;
     745            qt_last_mouse_receiver = w;
     746        }
     747        ignoreNextMouseReleaseEvent = true;
     748    }
     749    app_do_modal = qt_modal_stack != 0;
     750}
     751
     752bool qt_try_modal(QWidget *widget, QMSG *qmsg, MRESULT &rc)
     753{
     754    QWidget *top = 0;
     755
     756    if (QApplicationPrivate::tryModalHelper(widget, &top))
     757        return true;
     758
     759    int type = qmsg->msg;
     760
     761    bool block_event = false;
     762    if ((type >= WM_MOUSEFIRST && type <= WM_MOUSELAST) ||
     763        (type >= WM_EXTMOUSEFIRST && type <= WM_EXTMOUSELAST) ||
     764         type == WM_VSCROLL || type == WM_HSCROLL ||
     765         type == WM_U_MOUSELEAVE ||
     766         type == WM_CHAR) {
     767        if (type == WM_MOUSEMOVE) {
     768#ifndef QT_NO_CURSOR
     769            QCursor *c = qt_grab_cursor();
     770            if (!c)
     771                c = QApplication::overrideCursor();
     772            if (c) // application cursor defined
     773                WinSetPointer(HWND_DESKTOP, c->handle());
     774            else
     775                WinSetPointer(HWND_DESKTOP, QCursor(Qt::ArrowCursor).handle());
     776#endif // QT_NO_CURSOR
     777        } else if (type == WM_BUTTON1DOWN || type == type == WM_BUTTON2DOWN ||
     778                   type == WM_BUTTON3DOWN) {
     779            if (!top->isActiveWindow()) {
     780                top->activateWindow();
     781            } else {
     782                QApplication::beep();
     783            }
     784        }
     785        block_event = true;
     786    } else if (type == WM_CLOSE) {
     787        block_event = true;
     788    } else if (type == WM_SYSCOMMAND) {
     789        if (!(SHORT1FROMMP(qmsg->mp1) == SC_RESTORE && widget->isMinimized()))
     790            block_event = true;
     791    }
     792
     793    return !block_event;
    640794}
    641795
     
    12451399#endif
    12461400
     1401//
     1402// Close window event translation.
     1403//
     1404// This class is a friend of QApplication because it needs to emit the
     1405// lastWindowClosed() signal when the last top level widget is closed.
     1406//
     1407
     1408bool QETWidget::translateCloseEvent(const QMSG &)
     1409{
     1410    return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
     1411}
     1412
    12471413QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.