void g2Controller::__MouseHover(int x, int y) { // Ignore if not visible if(!GetVisibility()) return; // Update mouse to localized positions x -= pX; y -= pY; // If the user is moving and pressing, then do a drag event if(InController(x, y) && ControllerState == g2ControllerState_Pressed) __MouseDrag(x, y); // Else, if we are out of the controller, we are done dragging if(!InController(x, y) && ControllerState == g2ControllerState_Pressed) ControllerState = g2ControllerState_None; // Update the hovering actions MouseHover(x, y); // Update all children int QueueSize = (int)ChildObjects.size(); for(int i = 0; i < QueueSize; i++) { // Get child g2Controller* Child = ChildObjects.front(); ChildObjects.pop(); // Update child with localized coordinates Child->__MouseHover(x, y); // Put back ChildObjects.push(Child); } }
void g2Controller::__MouseHover(int x, int y) { // Ignore if not visible if(!GetVisibility()) return; // Update mouse to localized positions x -= pX; y -= pY; // If the user is moving and pressing, then do a drag event if(InController(x, y) && ((ControllerState & g2ControllerState_Pressed) != 0) ) __MouseDrag(x, y); // Update the hovering state if(InController(x, y)) ControllerState |= g2ControllerState_Hover; // Remove if needed else if((ControllerState & g2ControllerState_Hover) != 0) ControllerState ^= g2ControllerState_Hover; // Update the hovering actions MouseHover(x, y); // Update all children for(ChildObjectsIt Child = ChildObjects.begin(); Child != ChildObjects.end(); Child++) (*Child)->__MouseHover(x, y); }
void g2Controller::__MouseClick(g2MouseButton button, g2MouseClick state, int x, int y) { // Ignore if not visible if(!GetVisibility()) return; // Update mouse to localized positions x -= pX; y -= pY; // Are we in this object's volume and do we have a full left-click? if(InController(x, y) && button == g2MouseButton_Left && state == g2MouseClick_Down) ControllerState = g2ControllerState_Pressed; // Else, if there is a mouse release AND we are coming from a pressed state.... else if(InController(x, y) && button == g2MouseButton_Left && state == g2MouseClick_Up && ControllerState == g2ControllerState_Pressed) ControllerState = g2ControllerState_Clicked; // Else, reset to either hover or none... else if(InController(x, y)) ControllerState = g2ControllerState_Hover; // Else, no hovering, just nothing else ControllerState = g2ControllerState_None; // Update mouse click MouseClick(button, state, x, y); // Update all children int QueueSize = (int)ChildObjects.size(); for(int i = 0; i < QueueSize; i++) { // Get child g2Controller* Child = ChildObjects.front(); ChildObjects.pop(); // Update child window event Child->__MouseClick(button, state, x, y); // Put back ChildObjects.push(Child); } // Execute callback if(!GetDisabled() && GetControllerState() == g2ControllerState_Clicked && PressedCallback != 0) PressedCallback(this); }
void g2LabelEdit::MouseClick(g2MouseButton button, g2MouseClick state, int x, int y) { // If we are pressing and it's a left click, compute the best position if(InController(x, y) && button == g2MouseButton_Left && state == g2MouseClick_Down) { // Current offset of the character testing int OffsetX = 0; bool NewOffset = false; // Compute the best possible position for(size_t i = ViewIndex; i < strlen(TextBuffer) && !NewOffset; i++) { // Get this character's width and offset int ThisWidth, NextWidth; GetTheme()->GetCharacterSize(TextBuffer[i], &ThisWidth, NULL); GetTheme()->GetCharacterSize(TextBuffer[i + 1], &NextWidth, NULL); // Check for collision (little ceil hack with integers) if(x <= (OffsetX + (NextWidth + 1) / 2)) { CursorIndex = (int)i; NewOffset = true; } // Grow the offset over time OffsetX += ThisWidth + g2LabelEdit_CharacterSpacing; } // If no new offset, assume it is to far right if(!NewOffset) CursorIndex = (int)strlen(TextBuffer); } }
g2Controller* g2Controller::GetController(int x, int y) { // Assume nothing intersects g2Controller* ActiveController = NULL; // Update to a localized position x -= pX; y -= pY; // Check all children, do we interest? // We go through all of them as we don't want to change // the ordering which is important to rendering int QueueSize = (int)ChildObjects.size(); for(int i = 0; i < QueueSize; i++) { // Get child g2Controller* Child = ChildObjects.front(); ChildObjects.pop(); // Check but stop once at least one is found if(ActiveController == NULL) ActiveController = Child->GetController(x, y); // Put back ChildObjects.push(Child); } // No children have an intersection, as the parent do we intersect? if(ActiveController == NULL && InController(x, y)) ActiveController = this; // All done return ActiveController; }
g2Controller* g2Controller::GetController(int x, int y) { // Assume nothing intersects g2Controller* ActiveController = NULL; // Update to a localized position x -= pX; y -= pY; // Check all children, do we interest? // We go through all of them as we don't want to change // the ordering which is important to rendering // Ordering: [Back to Front] for(ChildObjectsIt Child = ChildObjects.begin(); Child != ChildObjects.end(); Child++) { // Save found object if not null (ignore completely if invisible) g2Controller* Found = (*Child)->GetController(x, y); if(Found != NULL && Found->GetVisibility()) ActiveController = Found; } // No children have an intersection, as the parent do we intersect? if(ActiveController == NULL && InController(x, y)) ActiveController = this; // All done return ActiveController; }
void g2RadioGroup::MouseClick(g2MouseButton button, g2MouseClick state, int x, int y) { // If we had a full key-press event within our collision box, change the active index as needed if(InController(x, y) && ((GetControllerState() & g2ControllerState_Clicked) == g2ControllerState_Clicked)) { // Get the size of a radio button int RadioHeight; GetTheme()->GetComponentSize(g2Theme_RadioButton, NULL, &RadioHeight); // For each radio button.. for(int i = 0; i < OptionCount; i++) { // What is the y pos of this row? int BottomRow = i * (RadioHeight + 1) + RadioHeight; if(y < BottomRow) { ActiveIndex = i; break; } } // Update the live index if(LiveIndex != NULL) *LiveIndex = ActiveIndex; } }
void g2Controller::__MouseClick(g2MouseButton button, g2MouseClick state, int x, int y) { // Ignore if not visible if(!GetVisibility()) return; // Update mouse to localized positions x -= pX; y -= pY; // Are we in this object's volume and do we have a full left-click? if(InController(x, y) && button == g2MouseButton_Left && state == g2MouseClick_Down) ControllerState |= g2ControllerState_Pressed; // Check for full click, if there is a mouse release AND we are coming from a pressed state.... if(InController(x, y) && button == g2MouseButton_Left && state == g2MouseClick_Up && ((ControllerState & g2ControllerState_Pressed) == g2ControllerState_Pressed)) ControllerState |= g2ControllerState_Clicked; // Are we no longer holding the mouse button down anymore? if((button == g2MouseButton_Left && state == g2MouseClick_Up) && ((ControllerState & g2ControllerState_Pressed) == g2ControllerState_Pressed)) ControllerState ^= g2ControllerState_Pressed; // Update mouse click; save an older version of the controller state, // in case the user destroys the clicked flag by calling GetControllerState() g2ControllerState OldControllerState = ControllerState; MouseClick(button, state, x, y); // If it's anything non-key-release if(state != g2MouseClick_Up) { // Apply update to all non-blocked objects // We must go from front-to-back ordering (which is the reverse // of what the rendering ordering is) for(ChildObjectsRevIt Child = ChildObjects.rbegin(); Child != ChildObjects.rend(); Child++) { // Child position int cx, cy; (*Child)->GetPos(&cx, &cy); // Stop applying on our first collision if we are in that controller // and it's on-screen (regardless of it being enabled or not) // Note that we must localize the coordinate for each controller if((*Child)->GetVisibility() && (*Child)->InController(x -cx , y - cy)) { (*Child)->__MouseClick(button, state, x, y); break; } } } // Else, apply release to everyone else { // Allow the recieving function to figure it's own event for(ChildObjectsRevIt Child = ChildObjects.rbegin(); Child != ChildObjects.rend(); Child++) (*Child)->__MouseClick(button, state, x, y); } // Execute callback (releases button-click flag) if(!GetDisabled() && ((OldControllerState & g2ControllerState_Clicked) == g2ControllerState_Clicked) && PressedCallback != 0) { // Callback and xor the controller state's click-event out PressedCallback(this); } }