mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
681 lines
18 KiB
C++
681 lines
18 KiB
C++
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||
|
*
|
||
|
* The contents of this file are subject to the Netscape Public License
|
||
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
||
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
||
|
* http://www.mozilla.org/NPL/
|
||
|
*
|
||
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||
|
* for the specific language governing rights and limitations under the
|
||
|
* NPL.
|
||
|
*
|
||
|
* The Initial Developer of this code under the NPL is Netscape
|
||
|
* Communications Corporation. Portions created by Netscape are
|
||
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||
|
* Reserved.
|
||
|
*/
|
||
|
// button.cpp : implementation file
|
||
|
//
|
||
|
#include "stdafx.h"
|
||
|
#include "fmabstra.h"
|
||
|
|
||
|
#include "button.h"
|
||
|
|
||
|
#include "libevent.h"
|
||
|
#include <windowsx.h>
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
#undef THIS_FILE
|
||
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
||
|
#endif
|
||
|
|
||
|
#ifndef _AFXDLL
|
||
|
#define new DEBUG_NEW // MSVC Debugging new...goes to regular new in release mode
|
||
|
#endif
|
||
|
|
||
|
#ifndef _WIN32
|
||
|
#define GET_WM_COMMAND_CMD(wp, lp) ((UINT)HIWORD(lp))
|
||
|
#endif
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CNetscapeButton dialog
|
||
|
|
||
|
IMPLEMENT_DYNAMIC(CNetscapeButton, CButton)
|
||
|
|
||
|
CNetscapeButton::CNetscapeButton(MWContext * context, LO_FormElementStruct * form, CWnd* pParent)
|
||
|
{
|
||
|
m_Context = context;
|
||
|
m_Form = form;
|
||
|
m_bDepressed = FALSE;
|
||
|
m_pwndEdit = NULL;
|
||
|
m_pPaneCX = PANECX(m_Context);
|
||
|
m_callBase = FALSE;
|
||
|
}
|
||
|
|
||
|
BEGIN_MESSAGE_MAP(CNetscapeButton, CButton)
|
||
|
ON_WM_CHAR()
|
||
|
ON_WM_SETFOCUS()
|
||
|
ON_WM_KILLFOCUS()
|
||
|
ON_WM_LBUTTONDBLCLK()
|
||
|
ON_WM_LBUTTONDOWN()
|
||
|
ON_WM_LBUTTONUP()
|
||
|
ON_WM_RBUTTONDBLCLK()
|
||
|
ON_WM_RBUTTONDOWN()
|
||
|
ON_WM_RBUTTONUP()
|
||
|
END_MESSAGE_MAP()
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CNetscapeButton message handlers
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//
|
||
|
// Called when the 'submit' event has been processed
|
||
|
//
|
||
|
static void
|
||
|
button_submit_closure(MWContext * pContext, LO_Element * pEle, int32 event,
|
||
|
void * pObj, ETEventStatus status)
|
||
|
{
|
||
|
if(status != EVENT_OK || !pEle || !pContext)
|
||
|
return;
|
||
|
FE_SubmitInputElement(pContext, pEle);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Called when the 'click' event has been processed
|
||
|
//
|
||
|
static void
|
||
|
button_click_closure(MWContext * pContext, LO_Element * pEle, int32 event,
|
||
|
void * pObj, ETEventStatus status)
|
||
|
{
|
||
|
|
||
|
// make sure every thing is OK
|
||
|
if(status == EVENT_PANIC || !pEle || !pContext)
|
||
|
return;
|
||
|
|
||
|
CNetscapeButton * pButton = (CNetscapeButton *) pObj;
|
||
|
LO_FormElementStruct * pForm = (LO_FormElementStruct *) pEle;
|
||
|
|
||
|
lo_FormElementMinimalData * min_data;
|
||
|
lo_FormElementToggleData * tog_data;
|
||
|
min_data = (lo_FormElementMinimalData *) pForm->element_data;
|
||
|
|
||
|
if(!min_data)
|
||
|
return;
|
||
|
|
||
|
if(status == EVENT_OK) {
|
||
|
switch(min_data->type) {
|
||
|
case FORM_TYPE_SUBMIT:
|
||
|
// send the event to libmocha --- do any further processing
|
||
|
// in our closure routine
|
||
|
JSEvent *event;
|
||
|
event = XP_NEW_ZAP(JSEvent);
|
||
|
event->type = EVENT_SUBMIT;
|
||
|
event->layer_id = pForm->layer_id;
|
||
|
|
||
|
ET_SendEvent(pContext, pEle, event,
|
||
|
button_submit_closure, pObj);
|
||
|
break;
|
||
|
|
||
|
case FORM_TYPE_RESET:
|
||
|
// libmocha has said it was OK to allow the reset to happen
|
||
|
// tell layout to go forward with the operation
|
||
|
// the world may not be safe after this so return
|
||
|
LO_ResetForm(pContext, pForm);
|
||
|
return;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
// Undo state operations.
|
||
|
switch(min_data->type) {
|
||
|
case FORM_TYPE_RADIO:
|
||
|
if(pButton->m_pLastSelectedRadio) {
|
||
|
tog_data = (lo_FormElementToggleData *)
|
||
|
pButton->m_pLastSelectedRadio->element_data;
|
||
|
if(!tog_data->toggled)
|
||
|
LO_FormRadioSet(ABSTRACTCX(pContext)->GetDocumentContext(),
|
||
|
pButton->m_pLastSelectedRadio);
|
||
|
|
||
|
CFormElement *pRadioButton = CFormElement::GetFormElement(ABSTRACTCX(pContext),
|
||
|
pButton->m_pLastSelectedRadio);
|
||
|
if(pRadioButton) {
|
||
|
pRadioButton->SetFormElementToggle(tog_data->toggled);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case FORM_TYPE_CHECKBOX:
|
||
|
tog_data = (lo_FormElementToggleData *) pForm->element_data;
|
||
|
if(tog_data->toggled)
|
||
|
tog_data->toggled = FALSE;
|
||
|
else
|
||
|
tog_data->toggled = TRUE;
|
||
|
|
||
|
if((pButton->GetCheck() ? TRUE : FALSE) != tog_data->toggled)
|
||
|
pButton->SetCheck(tog_data->toggled);
|
||
|
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// NFlags as per OnLButtonUp
|
||
|
//
|
||
|
//
|
||
|
// for FORM_TYPE_CHECKBOX, there are 3 places in this file call Click().
|
||
|
// 1. OnChar for space-key
|
||
|
// 2. OnButtonEvent, initiated by java script?
|
||
|
// 3. OnChildNotify maybe not necesary to handle this msg.
|
||
|
//
|
||
|
// We taggled state for 1 and 2.We do NOT taggle for 3. It always comes
|
||
|
// with 1 or 2. It is not clear whether item 3 is redundent, so it is
|
||
|
// not removed.
|
||
|
//
|
||
|
// Click() function is still called for all 3 cases.
|
||
|
//
|
||
|
// Messages interfare with debug, Trace statements are left for debuging.
|
||
|
//
|
||
|
// When change this code, please make sure radio-button and check-box
|
||
|
// work for both Tab-Space keys and mouse click(with out debug).
|
||
|
//
|
||
|
// Arthur 3/12/97, fix for #49682
|
||
|
//
|
||
|
void CNetscapeButton::Click(UINT nFlags, BOOL bNotify, BOOL &bReturnImmediately)
|
||
|
{
|
||
|
if(!m_Form || !m_Context)
|
||
|
return;
|
||
|
|
||
|
lo_FormElementMinimalData * min_data;
|
||
|
lo_FormElementToggleData * tog_data;
|
||
|
min_data = (lo_FormElementMinimalData *) m_Form->element_data;
|
||
|
char * pFileName;
|
||
|
if(!min_data)
|
||
|
return;
|
||
|
|
||
|
m_pLastSelectedRadio = NULL;
|
||
|
switch(min_data->type) {
|
||
|
|
||
|
case FORM_TYPE_RADIO:
|
||
|
tog_data = (lo_FormElementToggleData *) m_Form->element_data;
|
||
|
if(!tog_data->toggled) {
|
||
|
m_pLastSelectedRadio = LO_FormRadioSet(ABSTRACTCX(m_Context)->GetDocumentContext(), m_Form); // Turn off everyone else
|
||
|
}
|
||
|
if(GetCheck() != tog_data->toggled) {
|
||
|
SetCheck(tog_data->toggled);
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("Set\n");
|
||
|
#endif // DEBUG_aliu
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case FORM_TYPE_CHECKBOX:
|
||
|
// Make sure we don't already reflect that state, and don't do this
|
||
|
// if via OnChar, as MFC/Windows will do it for us.
|
||
|
if(bNotify == FALSE) {
|
||
|
tog_data = (lo_FormElementToggleData *) m_Form->element_data;
|
||
|
if(tog_data->toggled) {
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("Off ");
|
||
|
#endif // DEBUG_aliu
|
||
|
tog_data->toggled = FALSE;
|
||
|
} else {
|
||
|
tog_data->toggled = TRUE;
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("On ");
|
||
|
#endif // DEBUG_aliu
|
||
|
}
|
||
|
|
||
|
if((GetCheck() ? TRUE : FALSE) != tog_data->toggled) {
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("Set\n");
|
||
|
#endif // DEBUG_aliu
|
||
|
SetCheck(tog_data->toggled);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case FORM_TYPE_BUTTON:
|
||
|
break;
|
||
|
|
||
|
case FORM_TYPE_RESET:
|
||
|
case FORM_TYPE_SUBMIT:
|
||
|
// don't do anything yet --- send the OnClick to libmocha first
|
||
|
// Sigh don't make double submits
|
||
|
if (bNotify == TRUE) return;
|
||
|
break;
|
||
|
|
||
|
case FORM_TYPE_FILE:
|
||
|
pFileName = wfe_GetExistingFileName(m_hWnd,
|
||
|
szLoadString(IDS_FILE_UPLOAD),
|
||
|
HTM,
|
||
|
TRUE);
|
||
|
|
||
|
/* update both the widget display and the lo-datastructure */
|
||
|
if(pFileName && m_pwndEdit) {
|
||
|
m_pwndEdit->SetWindowText(pFileName);
|
||
|
|
||
|
if (m_Form->element_data->ele_text.current_text)
|
||
|
XP_FREE(m_Form->element_data->ele_text.current_text);
|
||
|
|
||
|
m_Form->element_data->ele_text.current_text = (PA_Block) pFileName;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
// send the event to libmocha --- do any further processing
|
||
|
// in our closure routine
|
||
|
JSEvent *event;
|
||
|
event = XP_NEW_ZAP(JSEvent);
|
||
|
event->type = EVENT_CLICK;
|
||
|
event->layer_id = m_Form->layer_id;
|
||
|
event->which = 1;
|
||
|
event->modifiers = (nFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (nFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
ET_SendEvent(m_Context, (LO_Element *)m_Form, event,
|
||
|
button_click_closure, this);
|
||
|
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
|
||
|
{
|
||
|
// CButton::OnChar( nChar, nRepCnt, nFlags);
|
||
|
if(( nChar == VK_SPACE || nChar == VK_RETURN) && !(nFlags>>14 & 1)) {
|
||
|
// buttons need a push.
|
||
|
BOOL bReturnImmediately = FALSE;
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("onCharClick ");
|
||
|
#endif // DEBUG_aliu
|
||
|
Click(0, FALSE, bReturnImmediately); //#49682 TRUE
|
||
|
if(bReturnImmediately) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnSetFocus(CWnd * pWnd)
|
||
|
{
|
||
|
CButton::OnSetFocus(pWnd); //must have this for fixing #51086, ref. #49682
|
||
|
if(m_Context && m_Form) {
|
||
|
// set tab focus to this element
|
||
|
CWinCX *pWinCX = WINCX(m_Context);
|
||
|
// if ((LO_Element *)m_Form == pWinCX->getLastTabFocusElement())
|
||
|
// return;
|
||
|
|
||
|
pWinCX->setFormElementTabFocus( (LO_Element *)m_Form );
|
||
|
|
||
|
// send the event to libmocha --- do any further processing
|
||
|
// in our closure routine
|
||
|
JSEvent *event;
|
||
|
event = XP_NEW_ZAP(JSEvent);
|
||
|
event->type = EVENT_FOCUS;
|
||
|
event->layer_id = m_Form->layer_id;
|
||
|
|
||
|
ET_SendEvent(m_Context, (LO_Element *)m_Form, event,
|
||
|
NULL, this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void CNetscapeButton::OnKillFocus(CWnd * pWnd)
|
||
|
{
|
||
|
CButton::OnKillFocus(pWnd);
|
||
|
if(m_Context && m_Form) {
|
||
|
// send the event to libmocha --- do any further processing
|
||
|
// in our closure routine
|
||
|
JSEvent *event;
|
||
|
event = XP_NEW_ZAP(JSEvent);
|
||
|
event->type = EVENT_BLUR;
|
||
|
event->layer_id = m_Form->layer_id;
|
||
|
|
||
|
ET_SendEvent(m_Context, (LO_Element *)m_Form, event, NULL, this);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnLButtonDblClk(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnLButtonDblClk(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context || ABSTRACTCX(m_Context)->IsDestroyed()) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
// Convert the point to something we understand.
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_MULTI_CLICK;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 1;
|
||
|
event.data = 2;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
CButton::OnLButtonDblClk(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnLButtonDown(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnLButtonDown(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Start capturing all mouse events.
|
||
|
if(m_hWnd) {
|
||
|
::SetCapture(m_hWnd);
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_DOWN;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 1;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
|
||
|
CButton::OnLButtonDown(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
void CNetscapeButton::OnLButtonUp(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnLButtonUp(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Start capturing all mouse events.
|
||
|
if(m_hWnd) {
|
||
|
::ReleaseCapture();
|
||
|
}
|
||
|
|
||
|
// translate mouse position to screen
|
||
|
CPoint cpScreenPoint(cpPoint);
|
||
|
ClientToScreen(&cpScreenPoint);
|
||
|
|
||
|
// Don't send the event on to JS if we're out of the button area.
|
||
|
if (::WindowFromPoint(cpScreenPoint) != m_hWnd) {
|
||
|
CButton::OnLButtonUp(uFlags, cpPoint);
|
||
|
m_bDepressed = FALSE;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_UP;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 1;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
CButton::OnLButtonUp(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnRButtonDblClk(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnRButtonDblClk(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_MULTI_CLICK;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 3;
|
||
|
event.data = 2;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
CButton::OnRButtonDblClk(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void CNetscapeButton::OnRButtonDown(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnRButtonDown(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Start capturing all mouse events.
|
||
|
if(m_hWnd) {
|
||
|
::SetCapture(m_hWnd);
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_DOWN;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 3;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
CButton::OnRButtonDown(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
void CNetscapeButton::OnRButtonUp(UINT uFlags, CPoint cpPoint) {
|
||
|
|
||
|
if (m_callBase) {
|
||
|
CButton::OnRButtonUp(uFlags, cpPoint);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Don't continue if this context is destroyed.
|
||
|
if(!m_Context) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Start capturing all mouse events.
|
||
|
if(m_hWnd) {
|
||
|
::ReleaseCapture();
|
||
|
}
|
||
|
|
||
|
MapWindowPoints(GetParent(), &cpPoint, 1);
|
||
|
|
||
|
XY Point;
|
||
|
m_pPaneCX->ResolvePoint(Point, cpPoint);
|
||
|
|
||
|
if (m_Context->compositor) {
|
||
|
CL_Event event;
|
||
|
fe_EventStruct fe_event;
|
||
|
|
||
|
fe_event.uFlags = uFlags;
|
||
|
fe_event.x = cpPoint.x;
|
||
|
fe_event.y = cpPoint.y;
|
||
|
|
||
|
event.type = CL_EVENT_MOUSE_BUTTON_UP;
|
||
|
event.fe_event = (void *)&fe_event;
|
||
|
event.fe_event_size = sizeof(fe_EventStruct);
|
||
|
event.x = Point.x;
|
||
|
event.y = Point.y;
|
||
|
event.which = 3;
|
||
|
event.modifiers = (uFlags & MK_SHIFT ? EVENT_SHIFT_MASK : 0)
|
||
|
| (uFlags & MK_CONTROL ? EVENT_CONTROL_MASK : 0)
|
||
|
| (GetKeyState(VK_MENU) < 0 ? EVENT_ALT_MASK : 0);
|
||
|
|
||
|
CL_DispatchEvent(m_Context->compositor,
|
||
|
&event);
|
||
|
}
|
||
|
else
|
||
|
CButton::OnRButtonUp(uFlags, cpPoint);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CNetscapeButton::OnButtonEvent(CL_EventType type, UINT nFlags, CPoint point) {
|
||
|
BOOL bReturnImmediately;
|
||
|
m_callBase = TRUE;
|
||
|
|
||
|
switch (type) {
|
||
|
case CL_EVENT_MOUSE_BUTTON_DOWN:
|
||
|
SendMessage(WM_LBUTTONDOWN, nFlags, MAKELONG(point.x, point.y));
|
||
|
// Hack since Windows stubbornly refuses to accept current state.
|
||
|
SetState(FALSE);
|
||
|
SetState(TRUE);
|
||
|
m_bDepressed = TRUE;
|
||
|
break;
|
||
|
case CL_EVENT_MOUSE_BUTTON_UP:
|
||
|
// Only send click event if button is already down.
|
||
|
if (m_bDepressed) {
|
||
|
SendMessage(WM_LBUTTONUP, nFlags, MAKELONG(point.x, point.y));
|
||
|
#ifdef DEBUG_aliu
|
||
|
TRACE0("ButtonEventClick ");
|
||
|
#endif // DEBUG_aliu
|
||
|
Click(nFlags, FALSE, bReturnImmediately);
|
||
|
m_bDepressed = FALSE;
|
||
|
}
|
||
|
break;
|
||
|
case CL_EVENT_MOUSE_BUTTON_MULTI_CLICK:
|
||
|
SendMessage(WM_LBUTTONDBLCLK, nFlags, MAKELONG(point.x, point.y));
|
||
|
break;
|
||
|
}
|
||
|
m_callBase = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
|