bool iDefaultCallback_onMouseMove(SWindow* win, SObject* obj, SVariable* varX, SVariable* varY, SVariable* varCtrl, SVariable* varAlt, SVariable* varShift, SVariable* varClick) { f64 lfPercent, lfX, lfY, lfWidth, lfHeight; s32 lnX, lnY; u32 lnClick; bool llCtrl, llAlt, llShift; SVariable* valueMin; // Make sure our environment is sane if (!iiDefaultCallback_processMouseVariables(varX, varY, varCtrl, varAlt, varShift, varClick, &lnX, &lnY, &llCtrl, &llAlt, &llShift, &lnClick)) return(false); // Do not continue consuming // If we're clicking on a radio button, adjust the dial if (lnClick != 0 && obj->objType == _OBJ_TYPE_RADIO) { // The mouse indicates the position // Determine theta lfWidth = (f64)(obj->rc.right - obj->rc.left); lfHeight = (f64)(obj->rc.bottom - obj->rc.top); lfX = (f64)lnX - (lfWidth / 2.0); lfY = (lfHeight - (f64)lnY) - (lfHeight / 2.0); lfPercent = atan2(lfY, lfX) / (M_PI * 2.0); if (lfPercent < 0.0) lfPercent += 1.0; valueMin = iObjProp_get_var_byIndex(obj, _INDEX_VALUE_MINIMUM); iObjProp_set_f64_direct(obj, _INDEX_VALUE, get_f64(valueMin) + (lfPercent * (iObjProp_get_f64_direct(obj, _INDEX_VALUE_MAXIMUM) - get_f64(valueMin)))); iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); } else if (obj->objType == _OBJ_TYPE_EDITBOX) { if ((lnClick & _MOUSE_LEFT_BUTTON) != 0) { // They are clicking and dragging // Need to navigate to the indicated x,y coordinate iSEM_navigateTo_pixelXY(obj->p.sem, obj, lnX, lnY); // Mark the mouse activity iSEM_selectStart(obj->p.sem, _SEM_SELECT_MODE_ANCHOR); // Redraw our changes iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); } } else if (obj->objType == _OBJ_TYPE_CAROUSEL) { // We always track mouse movements to hightlight and un-hightlight tabs return(iEvents_carouselMouseMove(win, obj, lnX, lnY, llCtrl, llAlt, llShift, lnClick)); } // Mouse moves continue to propagate all the way through, so as to signal appropriate enter and leave events return(true); }
bool iDefaultCallback_onMouseUp(SWindow* win, SObject* obj, SVariable* varX, SVariable* varY, SVariable* varCtrl, SVariable* varAlt, SVariable* varShift, SVariable* varClick) { s32 lnX, lnY; u32 lnClick; bool llCtrl, llAlt, llShift; POINT pt; // Make sure our environment is sane if (!iiDefaultCallback_processMouseVariables(varX, varY, varCtrl, varAlt, varShift, varClick, &lnX, &lnY, &llCtrl, &llAlt, &llShift, &lnClick)) return(false); // Do not continue consuming if (obj->objType == _OBJ_TYPE_CAROUSEL) { // Create a point pt.x = lnX; pt.y = lnY; // They are they outside of the client area? if (!PtInRect(&obj->rcClient, pt)) return(iEvents_carouselMouseUp(win, obj, lnX, lnY, llCtrl, llAlt, llShift, lnClick)); } // We are leaving this object, lower the flag obj->ev.isMouseDown = (obj->ev.thisClick != 0); // Indicate if the mouse is down here obj->ev.isMouseDown = false; iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); // Do not continue to propagate this message to other objects return(false); }
////////// // // Called when the user mouse ups (releases the mouse button) on a carousel somewhere outside of the client area // ////// bool iEvents_carouselMouseUp(SThisCode* thisCode, SWindow* win, SObject* obj, s32 lnX, s32 lnY, bool llCtrl, bool llAlt, bool llShift, u32 lnClick) { u32 lnTarget; bool llFocusChanged, llResult; SObjCarouselTabData* octd; // Make sure our environment is sane llResult = true; if (obj) { // Find the associated carousel sub-object lnTarget = iiEvents_carousel_findTarget(thisCode, win, obj, lnX, lnY, &octd, &llFocusChanged); switch (lnTarget) { case _EVENT_CAROUSEL_TAB: // Releasing the mouse on a tab iEngine_raise_event(thisCode, _EVENT_CAROUSEL_ONTABMOUSEUP, win, obj, (void*)false); llResult = false; break; } } // If something changed, we need to re-render if (llFocusChanged) { iObj_setDirtyRender_ascent(thisCode, obj, true); iWindow_render(thisCode, iWindow_findRoot_byObj(thisCode, obj), false); } // Signal if the message should continue propagating return(llResult); }
bool iDefaultCallback_onMouseLeave(SWindow* win, SObject* obj) { // Assume we consumed the leave, and that the parent doesn't need to receive it if (obj->ev.isMouseOver) { obj->ev.isMouseOver = false; iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); } // Do not continue to propagate this message to other objects return(false); }
bool iDefaultCallback_onMouseEnter(SWindow* win, SObject* obj) { // We are newly over this object, raise the flag obj->ev.isMouseDown = (obj->ev.thisClick != 0); // Indicate if the mouse is down here if (!obj->ev.isMouseOver) { obj->ev.isMouseOver = true; iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); } // Do not continue to propagate this message to other objects return(false); }
bool iDefaultCallback_onMouseWheel(SWindow* win, SObject* obj, SVariable* varX, SVariable* varY, SVariable* varCtrl, SVariable* varAlt, SVariable* varShift, SVariable* varClick, SVariable* varUnits) { s32 lnX, lnY, lnUnits; u32 lnClick; bool llCtrl, llAlt, llShift; // POINT pt; // Make sure our environment is sane if (!iiDefaultCallback_processMouseVariables(varX, varY, varCtrl, varAlt, varShift, varClick, &lnX, &lnY, &llCtrl, &llAlt, &llShift, &lnClick) || !iVariable_isValid(varUnits) || !iVariable_isTypeNumeric(varUnits)) return(false); // Do not continue consuming // Grab the units lnUnits = iiVariable_getAs_s32(varUnits, false, NULL, NULL); // Assume we consumed the mouse wheel, and that the parent doesn't need to receive it if (obj->objType == _OBJ_TYPE_EDITBOX) { // Ctrl+MouseWheel is a normal navigate if (llCtrl) { // They are just moving the cursor line iSEM_navigate(obj->p.sem, obj, lnUnits * ((llShift) ? -1 : -3), 0); // MouseWheel is a scroll } else { // They want to scroll the entire window, including the cursor line iSEM_scroll(obj->p.sem, obj, lnUnits * ((llShift) ? -1 : -3), 0); } iObj_setDirtyRender_ascent(obj, true); iWindow_render(win, false); } else if (obj->objType == _OBJ_TYPE_CAROUSEL) { // Create a point // pt.x = lnX; // pt.y = lnY; // They are they outside of the client area? return(iEvents_carouselMouseWheel(win, obj, lnX, lnY, llCtrl, llAlt, llShift, lnClick)); } else { // Continue propagating return(true); } // Do not continue to propagate this message to other objects return(false); }
bool iDefaultCallback_onKeyDown(SWindow* win, SObject* obj, SVariable* varCtrl, SVariable* varAlt, SVariable* varShift, SVariable* varCaps, SVariable* varAscii, SVariable* varVKey, SVariable* varIsCAS, SVariable* varIsAscii) { bool llRender; SObject* objCheckbox; SObject* objRender2; bool llCtrl, llAlt, llShift, llCaps, llIsCAS, llIsAscii; s16 lcAscii; u16 lnVKey; // Make sure our environment is sane if (!iiDefaultCallback_processKeyVariables(varCtrl, varAlt, varShift, varCaps, varAscii, varVKey, varIsCAS, varIsAscii, &llCtrl, &llAlt, &llShift, &llCaps, &llIsCAS, &llIsAscii, &lcAscii, &lnVKey)) return(false); // Do not continue consuming ////////// // See if we're on a checkbox ////// llRender = false; objCheckbox = NULL; if (obj->objType == _OBJ_TYPE_CHECKBOX) { // The object itself is a checkbox objCheckbox = obj; objRender2 = obj; } else if (obj->parent && obj->parent->objType == _OBJ_TYPE_CHECKBOX) { // The parent is a checkbox objCheckbox = obj->parent; objRender2 = obj; } if (objCheckbox) { if (lnVKey == VK_SPACE || lnVKey == VK_RETURN) { // Toggle the value and redraw llRender = true; iObjProp_set_s32_direct(objCheckbox, _INDEX_VALUE, ((iObjProp_get_s32_direct(objCheckbox, _INDEX_VALUE) == 0) ? 1 : 0)); iObj_setDirtyRender_ascent(objCheckbox, false); if (objRender2 != objCheckbox) iObj_setDirtyRender_ascent(objRender2, false); } else if (llShift && lnVKey == VK_TAB) { // Move to previous object llRender = iObj_setFocusObjectPrev(win, objCheckbox); } else if (lnVKey == VK_TAB) { // Move to next object llRender = iObj_setFocusObjectNext(win, objCheckbox); } else if (llIsAscii) { if ((u8)lcAscii == 't' || (u8)lcAscii == 'T' || (u8)lcAscii == 'y' || (u8)lcAscii == 'Y' || (u8)lcAscii == '1') { // Set it to on llRender = true; iObjProp_set_s32_direct(obj, _INDEX_VALUE, 1); iObj_setDirtyRender_ascent(objCheckbox, false); if (objRender2 != objCheckbox) iObj_setDirtyRender_ascent(objRender2, false); } else if ((u8)lcAscii == 'f' || (u8)lcAscii == 'F' || (u8)lcAscii == 'n' || (u8)lcAscii == 'N' || (u8)lcAscii == '0') { // Set it to off llRender = true; iObjProp_set_s32_direct(obj, _INDEX_VALUE, 0); iObj_setDirtyRender_ascent(objCheckbox, false); if (objRender2 != objCheckbox) iObj_setDirtyRender_ascent(objRender2, false); } } } else { // Not a checkbox if (llShift && lnVKey == VK_TAB) { // Move to previous object llRender = iObj_setFocusObjectPrev(win, obj); } else if (lnVKey == VK_TAB) { // Move to next object llRender = iObj_setFocusObjectNext(win, obj); } } // Redraw if need be if (llRender) { // Redraw the checkbox if needed if (objCheckbox) iObj_setSize(objCheckbox, objCheckbox->rc.left, objCheckbox->rc.top, objCheckbox->rc.right - objCheckbox->rc.left, objCheckbox->rc.bottom - objCheckbox->rc.top); // Redraw the window iWindow_render(win, false); } // Do not continue to propagate this message to other objects return(false); }
bool iDefaultCallback_onMouseDown(SWindow* win, SObject* obj, SVariable* varX, SVariable* varY, SVariable* varCtrl, SVariable* varAlt, SVariable* varShift, SVariable* varClick) { bool llMouseDown, llResult, llFocusChanged; f64 lfPercent, lfX, lfY, lfWidth, lfHeight, lfValue; s32 lnX, lnY; u32 lnClick; bool llCtrl, llAlt, llShift; POINT pt; SVariable* valueMin; SObject* objRoot; // Make sure our environment is sane if (!iiDefaultCallback_processMouseVariables(varX, varY, varCtrl, varAlt, varShift, varClick, &lnX, &lnY, &llCtrl, &llAlt, &llShift, &lnClick)) return(false); // Do not continue consuming // Set the flags llMouseDown = true; llResult = true; // If focus isn't already set on this control, set focus on this control if (!obj->p.hasFocus) { objRoot = iObj_find_rootmostObject(obj); if (objRoot) iObj_clearFocus(win, objRoot, true, true); iObj_setFocus(win, obj, true); iObj_setDirtyRender_ascent(obj, true, true); llFocusChanged = true; } else { llFocusChanged = false; } // For forms, they can be clicking down on special things for various operations if (obj->parent && obj->parent->objType == _OBJ_TYPE_FORM && win->obj == obj->parent) { // Left button only? if (win->mouseCurrent.buttonLeft && !win->mouseCurrent.buttonMiddle && !win->mouseCurrent.buttonRight) { // We're on the top-level form for the window if (propIsName_byText(obj, cgcName_iconMove) || propIsName_byText(obj, cgcName_caption)) { // We're on the _move icon or the caption, which means they want to move the window win->isMoving = true; memcpy(&win->rcMoveResizeStart, &win->rc, sizeof(win->rcMoveResizeStart)); memcpy(&win->mouseMoveResizeStart, &win->mouseCurrent, sizeof(win->mouseMoveResizeStart)); // } else if (iDatum_compare(&varName->value, cgcName_iconScaleUl, sizeof(cgcName_iconScaleUl) - 1) == 0) { // // We're on the upper-left scaling arrow // } else if (iDatum_compare(&varName->value, cgcName_iconScaleUr, sizeof(cgcName_iconScaleUr) - 1) == 0) { // // We're on the upper-right scaling arrow // } else if (iDatum_compare(&varName->value, cgcName_iconScaleLr, sizeof(cgcName_iconScaleLr) - 1) == 0) { // // We're on the lower-right scaling arrow // } else if (iDatum_compare(&varName->value, cgcName_iconScaleLl, sizeof(cgcName_iconScaleLl) - 1) == 0) { // // We're on the lower-left scaling arrow } } } if (obj->parent && obj->parent->objType == _OBJ_TYPE_CHECKBOX) { // For checkboxes, we toggle // They're clicking on a checkbox, toggle the value and re-render iObjProp_set_s32_direct(obj->parent, _INDEX_VALUE, ((iObjProp_get_s32_direct(obj->parent, _INDEX_VALUE) != 0) ? 0 : 1)); // Force a refresh obj->parent->isDirtyRender = true; obj->parent->isDirtyPublish = true; // Do not continue to propagate llResult = false; } else if (obj->objType == _OBJ_TYPE_EDITBOX) { // Need to navigate to the indicated x,y coordinate iSEM_navigateTo_pixelXY(obj->p.sem, obj, lnX, lnY); // Mark the mouse activity if (!llShift) iSEM_selectStop(obj->p.sem); else iSEM_selectStart(obj->p.sem, _SEM_SELECT_MODE_ANCHOR); // Do not continue to propagate llResult = false; } else if (obj->objType == _OBJ_TYPE_RADIO) { // The mouse indicates the position // Determine theta lfWidth = (f64)(obj->rc.right - obj->rc.left); lfHeight = (f64)(obj->rc.bottom - obj->rc.top); lfX = (f64)lnX - (lfWidth / 2.0); lfY = (lfHeight - (f64)lnY) - (lfHeight / 2.0); lfPercent = atan2(lfY, lfX) / (M_PI * 2.0); if (lfPercent < 0.0) lfPercent += 1.0; valueMin = iObjProp_get_var_byIndex(obj, _INDEX_VALUE_MINIMUM); lfValue = get_f64(valueMin) + (lfPercent * (iObjProp_get_f64_direct(obj, _INDEX_VALUE_MAXIMUM) - get_f64(valueMin))); iObjProp_set_f64_direct(obj, _INDEX_VALUE, lfValue); // Do not continue to propagate llResult = false; } else if (obj->objType == _OBJ_TYPE_CAROUSEL) { // Create a point pt.x = lnX; pt.y = lnY; // They are they outside of the client area? if (!PtInRect(&obj->rcClient, pt)) return(iEvents_carouselMouseDown(win, obj, lnX, lnY, llCtrl, llAlt, llShift, lnClick)); } else { // Assume we consumed the mouse down event, and that the parent doesn't need to receive it switch (obj->objType) { case _OBJ_TYPE_IMAGE: if (propIsName_byText(obj, cgcName_iconClose)) { // Close iVjr_shutdown(); // They clicked quit return(false); // When we get here, the object no longer exists } else if (propIsName_byText(obj, cgcName_iconMove)) { // Move llMouseDown = false; obj->ev.isMouseOver = false; iWindow_move(win); } else if (propIsName_byText(obj, cgcName_iconMinimize)) { // Minimize llMouseDown = false; obj->ev.isMouseOver = false; iWindow_minimize(win); } else if (propIsName_byText(obj, cgcName_iconMaximize)) { // Maximize llMouseDown = false; obj->ev.isMouseOver = false; iWindow_maximize(win); } break; } } // Update our condition obj->ev.isMouseDown = llMouseDown; iObj_setDirtyRender_ascent(obj, true, true); iWindow_render(win, llFocusChanged); // Do not continue to propagate this message to other objects return(llResult); }