//====================================================================== //====================================================================== NvUIEventResponse NvUIButton::HandleReaction(const NvUIReaction& react) { if (react.code == m_action) { if (react.uid == 0) // sent from 'system' rather than a control. { if (GetDrawState() != react.state ) { SetDrawState(react.state); SetPrevDrawState(0); } } else if (m_type==NvUIButtonType::RADIO) { if (react.uid != m_uiuid) // unselect any other buttons with same actionCode { if (GetDrawState() == NvUIButtonState::SELECTED ) { SetDrawState(NvUIButtonState::ACTIVE); SetPrevDrawState(0); } } else // we sent the reaction... { } } } return nvuiEventNotHandled; // !!!!TBD }
void SwrSetDsFunc( HANDLE hContext, PFN_DS_FUNC pfnFunc) { API_STATE* pApiState = GetDrawState(GetContext(hContext)); pApiState->pfnDsFunc = pfnFunc; }
//====================================================================== //====================================================================== void NvUIButton::Draw(const NvUIDrawState &drawState) { if (!m_isVisible) return; const uint32_t state = GetDrawState(); // eventually this will do some state-based handling for active/inactive, pushed NvUIElement *drawme = m_visrep[state]; if (drawme!=NULL) // pass to our visrep. drawme->Draw(drawState); if (m_title) { NvUIDrawState newState(drawState); // !!!!TBD TODO // ... instead of using alpha, we could draw some a translucent box using our uirect. if (m_visrep[0]==NULL && m_visrep[1]==NULL && m_visrep[2]==NULL) { // then modulate alpha based on draw state. if (state==NvUIButtonState::INACTIVE) { newState.alpha *= 0.25f; // very 'dim' } else if (state==NvUIButtonState::SELECTED) { newState.alpha *= 0.75f; // slightly 'dimmed' } // else leave alone. } m_title->Draw(newState); } }
void SwrSetGsFunc( HANDLE hContext, PFN_GS_FUNC pfnGsFunc) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->pfnGsFunc = pfnGsFunc; }
void SwrSetPixelShaderState( HANDLE hContext, SWR_PS_STATE *pPSState) { API_STATE *pState = GetDrawState(GetContext(hContext)); pState->psState = *pPSState; }
void SwrSetFrontendState( HANDLE hContext, SWR_FRONTEND_STATE *pFEState) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->frontendState = *pFEState; }
void SwrSetGsState( HANDLE hContext, SWR_GS_STATE *pGSState) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->gsState = *pGSState; }
void SwrSetBlendState( HANDLE hContext, SWR_BLEND_STATE *pBlendState) { API_STATE *pState = GetDrawState(GetContext(hContext)); memcpy(&pState->blendState, pBlendState, sizeof(SWR_BLEND_STATE)); }
void SwrSetTsState( HANDLE hContext, SWR_TS_STATE *pState) { API_STATE* pApiState = GetDrawState(GetContext(hContext)); pApiState->tsState = *pState; }
void SetupDefaultState(SWR_CONTEXT *pContext) { API_STATE* pState = GetDrawState(pContext); pState->rastState.cullMode = SWR_CULLMODE_NONE; pState->rastState.frontWinding = SWR_FRONTWINDING_CCW; }
void SwrSetVertexFunc( HANDLE hContext, PFN_VERTEX_FUNC pfnVertexFunc) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->pfnVertexFunc = pfnVertexFunc; }
void SwrSetSoState( HANDLE hContext, SWR_STREAMOUT_STATE* pSoState) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->soState = *pSoState; }
void SwrSetBackendState( HANDLE hContext, SWR_BACKEND_STATE *pBEState) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->backendState = *pBEState; }
void SwrSetFetchFunc( HANDLE hContext, PFN_FETCH_FUNC pfnFetchFunc) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->pfnFetchFunc = pfnFetchFunc; }
void SwrSetIndexBuffer( HANDLE hContext, const SWR_INDEX_BUFFER_STATE* pIndexBuffer) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->indexBuffer = *pIndexBuffer; }
void SwrSetDepthStencilState( HANDLE hContext, SWR_DEPTH_STENCIL_STATE *pDSState) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->depthStencilState = *pDSState; }
void SwrSetRastState( HANDLE hContext, const SWR_RASTSTATE *pRastState) { SWR_CONTEXT *pContext = GetContext(hContext); API_STATE* pState = GetDrawState(pContext); memcpy(&pState->rastState, pRastState, sizeof(SWR_RASTSTATE)); }
void SwrSetBlendFunc( HANDLE hContext, uint32_t renderTarget, PFN_BLEND_JIT_FUNC pfnBlendFunc) { SWR_ASSERT(renderTarget < SWR_NUM_RENDERTARGETS); API_STATE *pState = GetDrawState(GetContext(hContext)); pState->pfnBlendFunc[renderTarget] = pfnBlendFunc; }
void SwrSetCsFunc( HANDLE hContext, PFN_CS_FUNC pfnCsFunc, uint32_t totalThreadsInGroup) { API_STATE* pState = GetDrawState(GetContext(hContext)); pState->pfnCsFunc = pfnCsFunc; pState->totalThreadsInGroup = totalThreadsInGroup; }
void SwrSetScissorRects( HANDLE hContext, uint32_t numScissors, const BBOX* pScissors) { SWR_ASSERT(numScissors <= KNOB_NUM_VIEWPORTS_SCISSORS, "Invalid number of scissor rects."); API_STATE* pState = GetDrawState(GetContext(hContext)); memcpy(&pState->scissorRects[0], pScissors, numScissors * sizeof(BBOX)); };
void SwrSetSoBuffers( HANDLE hContext, SWR_STREAMOUT_BUFFER* pSoBuffer, uint32_t slot) { API_STATE* pState = GetDrawState(GetContext(hContext)); SWR_ASSERT((slot < 4), "There are only 4 SO buffer slots [0, 3]\nSlot requested: %d", slot); pState->soBuffer[slot] = *pSoBuffer; }
void SwrSetSoFunc( HANDLE hContext, PFN_SO_FUNC pfnSoFunc, uint32_t streamIndex) { API_STATE* pState = GetDrawState(GetContext(hContext)); SWR_ASSERT(streamIndex < MAX_SO_STREAMS); pState->pfnSoFunc[streamIndex] = pfnSoFunc; }
void SwrSetViewports( HANDLE hContext, uint32_t numViewports, const SWR_VIEWPORT* pViewports, const SWR_VIEWPORT_MATRIX* pMatrices) { SWR_ASSERT(numViewports <= KNOB_NUM_VIEWPORTS_SCISSORS, "Invalid number of viewports."); SWR_CONTEXT *pContext = GetContext(hContext); API_STATE* pState = GetDrawState(pContext); memcpy(&pState->vp[0], pViewports, sizeof(SWR_VIEWPORT) * numViewports); if (pMatrices != nullptr) { memcpy(&pState->vpMatrix[0], pMatrices, sizeof(SWR_VIEWPORT_MATRIX) * numViewports); } else { // Compute default viewport transform. for (uint32_t i = 0; i < numViewports; ++i) { if (pContext->driverType == DX) { pState->vpMatrix[i].m00 = pState->vp[i].width / 2.0f; pState->vpMatrix[i].m11 = -pState->vp[i].height / 2.0f; pState->vpMatrix[i].m22 = pState->vp[i].maxZ - pState->vp[i].minZ; pState->vpMatrix[i].m30 = pState->vp[i].x + pState->vpMatrix[i].m00; pState->vpMatrix[i].m31 = pState->vp[i].y - pState->vpMatrix[i].m11; pState->vpMatrix[i].m32 = pState->vp[i].minZ; } else { // Standard, with the exception that Y is inverted. pState->vpMatrix[i].m00 = (pState->vp[i].width - pState->vp[i].x) / 2.0f; pState->vpMatrix[i].m11 = (pState->vp[i].y - pState->vp[i].height) / 2.0f; pState->vpMatrix[i].m22 = (pState->vp[i].maxZ - pState->vp[i].minZ) / 2.0f; pState->vpMatrix[i].m30 = pState->vp[i].x + pState->vpMatrix[i].m00; pState->vpMatrix[i].m31 = pState->vp[i].height + pState->vpMatrix[i].m11; pState->vpMatrix[i].m32 = pState->vp[i].minZ + pState->vpMatrix[i].m22; // Now that the matrix is calculated, clip the view coords to screen size. // OpenGL allows for -ve x,y in the viewport. pState->vp[i].x = std::max(pState->vp[i].x, 0.0f); pState->vp[i].y = std::max(pState->vp[i].y, 0.0f); } } } updateGuardband(pState); }
void SwrSetVertexBuffers( HANDLE hContext, uint32_t numBuffers, const SWR_VERTEX_BUFFER_STATE* pVertexBuffers) { API_STATE* pState = GetDrawState(GetContext(hContext)); for (uint32_t i = 0; i < numBuffers; ++i) { const SWR_VERTEX_BUFFER_STATE *pVB = &pVertexBuffers[i]; pState->vertexBuffers[pVB->index] = *pVB; } }
//====================================================================== //====================================================================== NvUIEventResponse NvUIButton::HandleFocusEvent(NvFocusEvent::Enum evt) { NvUIEventResponse r = nvuiEventNotHandled; if (!GetVisibility()) return r; // we only handle PRESS focus actions for right now. if (evt!=NvFocusEvent::ACT_PRESS) return r; uint32_t st = GetDrawState(); // we don't handle actions if we're inactive. if (st == NvUIButtonState::INACTIVE) return r; if (m_type==NvUIButtonType::CHECK) { // then toggle. if (st == NvUIButtonState::ACTIVE) st = NvUIButtonState::SELECTED; else st = NvUIButtonState::ACTIVE; SetDrawState(st); } else if (m_type==NvUIButtonType::RADIO) { // then select THIS radio st = NvUIButtonState::SELECTED; SetDrawState(st); } else // push button { // fake that we're pushed in... st = NvUIButtonState::ACTIVE; // but don't set drawstate! } NvUIReaction &react = GetReactionEdit(); react.uid = m_uiuid; react.code = m_action; react.state = st; // in case someone is looking for a value for this reaction. if (m_type==NvUIButtonType::RADIO) react.ival = m_subcode; else react.ival = react.state; // pass draw state as value. react.flags = NvReactFlag::NONE; r = nvuiEventHandledInteractReaction; VERBOSE_PRINT("}}}}}} prepped reaction\n"); return r; }
void SwrSetLinkage( HANDLE hContext, uint32_t mask, const uint8_t* pMap) { API_STATE* pState = GetDrawState(GetContext(hContext)); static const uint8_t IDENTITY_MAP[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }; static_assert(sizeof(IDENTITY_MAP) == sizeof(pState->linkageMap), "Update for new value of MAX_ATTRIBUTES"); pState->linkageMask = mask; pState->linkageCount = _mm_popcnt_u32(mask); if (!pMap) { pMap = IDENTITY_MAP; } memcpy(pState->linkageMap, pMap, pState->linkageCount); }
//====================================================================== //====================================================================== NvUIEventResponse NvUIButton::HandleEvent(const NvGestureEvent &gdata, NvUST timeUST, NvUIElement *hasInteract) { bool hit = false; if (!m_isVisible || (GetDrawState()==NvUIButtonState::INACTIVE) #ifndef BTN_SUPPORTS_HOVER || (gdata.kind<=NvGestureKind::HOVER) #else || (gdata.kind<NvGestureKind::HOVER) || (gdata.kind==NvGestureKind::HOVER && !m_wantsHover) #endif ) return nvuiEventNotHandled; bool possibleSlideTarget = false; if (gdata.uid == m_reactGestureUID) // then we're done? { VERBOSE_PRINT("early exit same event UID"); if (this==hasInteract) return nvuiEventHandledInteract; else return nvuiEventHandled; // since we flagged the triggered UID... } // check if this is a valid, non-focused/non-active slide-focus target if (gdata.kind==NvGestureKind::DRAG // is a drag/slide going on && GetSlideInteractGroup() // we have a focus group ID && GetSlideInteractGroup() == GetActiveSlideInteractGroup()) // and our ID matches active ID { if (!m_wasHit // if we aren't flagged as active/hit && hasInteract // focus isn't null (early exit) -- note focus could be a higher container rather than another button. // && this!=hasInteract // aren't the focused element (sorta redundant check) ) { possibleSlideTarget = true; } } if (!possibleSlideTarget && gdata.uid == m_failedHitUID) { VERBOSE_PRINT("early exit failed hit"); return nvuiEventNotHandled; } // verify we've been hit.. hit = m_rect.Inside((float)(gdata.x+gdata.dx), (float)(gdata.y+gdata.dy), m_hitMarginWide, m_hitMarginTall); //VERBOSE_PRINT("[event 0x%x] hit = %s, focus = 0x%x\n", (unsigned int)(gdata.uid), hit?"yes":"no", (uint32_t)hasInteract); if (possibleSlideTarget) { // use drag dx/dy for hit detection of CURRENT position, not gesture start loc. if (!hit) { m_wasHit = false; m_failedHitUID = gdata.uid; // so we don't retest. VERBOSE_PRINT("!!!!!> slide target 0x%x not hit\n", (uint32_t)this); return nvuiEventNotHandled; // we're done. } VERBOSE_PRINT("!!!!!> slide target 0x%x hit\n", (uint32_t)this); m_wasHit = true; m_failedHitUID = 0; // so we retest. SetPrevDrawState(GetDrawState()); // .. anything special here?? // lostInteract on other element will happen in container above us. } else // !!!!!TBD // I'm getting MULTIPLE PRESS EVENTS!!!?!?! if (!m_wasHit && gdata.kind==NvGestureKind::PRESS) { if (!hit) { m_wasHit = false; m_failedHitUID = gdata.uid; // so we don't retest. return nvuiEventNotHandled; // we're done. } m_wasHit = true; VERBOSE_PRINT("!!!!!> not hit -> got hit\n"); SetPrevDrawState(GetDrawState()); if (GetDrawState()==0 && GetSlideInteractGroup()) // we set the active group on press. SetActiveSlideInteractGroup(GetSlideInteractGroup()); else SetActiveSlideInteractGroup(0); if (possibleSlideTarget) // we are now! { // .. anything special here?? // lostInteract on other element will happen in container above us. } } else if (!m_wasHit) { VERBOSE_PRINT("!!!!!> not hit -> not hit\n"); #if later // if we get here we: // weren't a valid slide target // weren't getting a press (above) // hadn't gotten a press yet (!wasHit) // hadn't ignored a press (uid exit would have hit above) if (gdata.kind==NV_GESTURE_NONE) { // TODO -- I realize, this isn't great code. trying to get something starter-ish in place. // already calc'd hit. if (hit) { if (!m_wasHover) SetDrawState(1); return nvuiEventHandledHover; } else //!hit { if (!m_wasHover) SetDrawState(0); } } #endif return nvuiEventNotHandled; } else if (m_wasHit && gdata.kind==NvGestureKind::DRAG) { // we're dragging. but might not be INSIDE/hit. VERBOSE_PRINT("> drag\n"); } else if ( // gdata.kind==NV_GESTURE_FLICK || gdata.kind&NvGestureKind::MASK_RELEASED) // any release state!!! { // already calc'd hit. VERBOSE_PRINT("!!!!!> got release\n"); } else if (m_wasHit || this==hasInteract) // keep focus. { VERBOSE_PRINT("!!!!!> was hit, keep focus\n"); return nvuiEventHandledInteract; } VERBOSE_PRINT("!!!!!> secondary processing...\n"); if (hit) { VERBOSE_PRINT("}}}} was hit\n"); if (m_type==NvUIButtonType::CHECK) { // !!!!TBD if (GetPrevDrawState() == GetDrawState()) // we haven't flipped yet { if (GetDrawState()==NvUIButtonState::ACTIVE) SetDrawState(NvUIButtonState::SELECTED); else SetDrawState(NvUIButtonState::ACTIVE); } } else SetDrawState(NvUIButtonState::SELECTED); } else if (!m_stickyClick) { VERBOSE_PRINT("}}}} not hit\n"); if (m_type!=NvUIButtonType::PUSH) { // !!!!TBD //if (m_prevDrawState != m_currDrawState) // we flipped, put BACK SetDrawStatePrev(); } else SetDrawState(NvUIButtonState::ACTIVE); } // if we came this far, we're hit. are we done? if (gdata.kind & NvGestureKind::MASK_RELEASED) // we're done? { VERBOSE_PRINT("}}}} got release !!! !!! !!!! !!! !!!\n"); NvUIEventResponse r = nvuiEventHandled; if (hit) // on the release, what's our curr state?? { VERBOSE_PRINT("}}}}}} hit, any reaction?\n"); if (gdata.uid != m_reactGestureUID) { // !!!!TBD if a radio button, we really want to stash the // state at PRESSED time, so that we know whether to send // an event at all! m_reactGestureUID = gdata.uid; // so we don't retrigger. NvUIReaction &react = GetReactionEdit(); react.uid = m_uiuid; react.code = m_action; react.state = GetDrawState(); // in case someone is looking for a value for this reaction. if (m_type==NvUIButtonType::RADIO) react.ival = m_subcode; else react.ival = react.state; // pass draw state as value. react.flags = NvReactFlag::NONE; react.causeKind = gdata.kind; react.causeIndex = gdata.index; r = nvuiEventHandledInteractReaction; // KEEP FOCUS FOR NOW -- else maybe->tap issues !!!!TBD VERBOSE_PRINT("}}}}}} prepped reaction\n"); } } // reset draw state if button type is Push // AFTER reaction, so we get state correct in the message. if (m_type==NvUIButtonType::PUSH) SetDrawState(NvUIButtonState::ACTIVE); m_wasHit = false; // reset! return r; } if (m_wasHit || this==hasInteract) // keep focus. { NvUIEventResponse r = nvuiEventWantsInteract; if (hit) { r = nvuiEventHandledInteract; } else { VERBOSE_PRINT("} keep focus ftm..\n"); } return r; } return nvuiEventNotHandled; }