From dafe5329396fb73b09b084c9022ac17c0ae40b8b Mon Sep 17 00:00:00 2001 From: dborth Date: Fri, 10 Apr 2009 08:12:37 +0000 Subject: [PATCH] draggable scrollbars --- source/ngc/gui/gui.h | 38 ++++++++++++++++ source/ngc/gui/gui_button.cpp | 49 +++++++++++++++++--- source/ngc/gui/gui_element.cpp | 67 ++++++++++++++++++++++++++-- source/ngc/gui/gui_filebrowser.cpp | 48 ++++++++++++++++++-- source/ngc/gui/gui_image.cpp | 4 +- source/ngc/gui/gui_imagedata.cpp | 4 +- source/ngc/gui/gui_keyboard.cpp | 4 +- source/ngc/gui/gui_optionbrowser.cpp | 4 +- source/ngc/gui/gui_savebrowser.cpp | 4 +- source/ngc/gui/gui_sound.cpp | 4 +- source/ngc/gui/gui_text.cpp | 4 +- source/ngc/gui/gui_trigger.cpp | 17 ++++++- source/ngc/gui/gui_window.cpp | 4 +- source/ngc/input.h | 2 + 14 files changed, 224 insertions(+), 29 deletions(-) diff --git a/source/ngc/gui/gui.h b/source/ngc/gui/gui.h index 57b708c..b5f30bb 100644 --- a/source/ngc/gui/gui.h +++ b/source/ngc/gui/gui.h @@ -72,6 +72,7 @@ enum STATE_DEFAULT, STATE_SELECTED, STATE_CLICKED, + STATE_HELD, STATE_DISABLED }; @@ -154,6 +155,30 @@ class GuiElement //!Considers vertical alignment, y offset, height, and parent element's GetTop() / GetHeight() values //!\return top coordinate int GetTop(); + //!Sets the minimum y offset of the element + //!\param y Y offset + void SetMinY(int y); + //!Gets the minimum y offset of the element + //!\return Minimum Y offset + int GetMinY(); + //!Sets the maximum y offset of the element + //!\param y Y offset + void SetMaxY(int y); + //!Gets the maximum y offset of the element + //!\return Maximum Y offset + int GetMaxY(); + //!Sets the minimum x offset of the element + //!\param x X offset + void SetMinX(int x); + //!Gets the minimum x offset of the element + //!\return Minimum X offset + int GetMinX(); + //!Sets the maximum x offset of the element + //!\param x X offset + void SetMaxX(int x); + //!Gets the maximum x offset of the element + //!\return Maximum X offset + int GetMaxX(); //!Gets the current width of the element. Does not currently consider the scale //!\return width int GetWidth(); @@ -173,12 +198,18 @@ class GuiElement //!Checks whether or not the element is clickable //!\return true if clickable, false otherwise bool IsClickable(); + //!Checks whether or not the element is draggable + //!\return true if draggable, false otherwise + bool IsDraggable(); //!Sets whether or not the element is selectable //!\param s Selectable void SetSelectable(bool s); //!Sets whether or not the element is clickable //!\param c Clickable void SetClickable(bool c); + //!Sets whether or not the element is draggable + //!\param c Draggable + void SetDraggable(bool d); //!Gets the element's current state //!\return state int GetState(); @@ -271,6 +302,10 @@ class GuiElement int height; //!< Element height int xoffset; //!< Element X offset int yoffset; //!< Element Y offset + int ymin; //!< Element's min Y offset allowed + int ymax; //!< Element's max Y offset allowed + int xmin; //!< Element's min X offset allowed + int xmax; //!< Element's max X offset allowed int xoffsetDyn; //!< Element X offset, dynamic (added to xoffset value for animation effects) int yoffsetDyn; //!< Element Y offset, dynamic (added to yoffset value for animation effects) int alpha; //!< Element alpha value (0-255) @@ -287,8 +322,10 @@ class GuiElement int alignmentHor; //!< Horizontal element alignment, respective to parent element (LEFT, RIGHT, CENTRE) int alignmentVert; //!< Horizontal element alignment, respective to parent element (TOP, BOTTOM, MIDDLE) int state; //!< Element state (DEFAULT, SELECTED, CLICKED, DISABLED) + int stateChan; //!< Which controller channel is responsible for the last change in state bool selectable; //!< Whether or not this element selectable (can change to SELECTED state) bool clickable; //!< Whether or not this element is clickable (can change to CLICKED state) + bool draggable; //!< Whether or not this element is draggable (can change to HELD state) GuiTrigger * trigger[2]; //!< GuiTriggers (input actions) that this element responds to GuiElement * parentElement; //!< Parent element UpdateCallback updateCB; //!< Callback function to call when this element is updated @@ -616,6 +653,7 @@ class GuiFileBrowser : public GuiElement GuiSound * btnSoundOver; GuiSound * btnSoundClick; GuiTrigger * trigA; + GuiTrigger * trigHeldA; }; typedef struct _optionlist { diff --git a/source/ngc/gui/gui_button.cpp b/source/ngc/gui/gui_button.cpp index 45fcf45..51b3fed 100644 --- a/source/ngc/gui/gui_button.cpp +++ b/source/ngc/gui/gui_button.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_button.cpp * @@ -115,19 +115,19 @@ void GuiButton::Draw() return; // draw image - if(state == STATE_SELECTED && imageOver) + if((state == STATE_SELECTED || state == STATE_HELD) && imageOver) imageOver->Draw(); else if(image) image->Draw(); // draw icon - if(state == STATE_SELECTED && iconOver) + if((state == STATE_SELECTED || state == STATE_HELD) && iconOver) iconOver->Draw(); else if(icon) icon->Draw(); // draw text for(int i=0; i<3; i++) { - if(state == STATE_SELECTED && labelOver[i]) + if((state == STATE_SELECTED || state == STATE_HELD) && labelOver[i]) labelOver[i]->Draw(); else if(label[i]) label[i]->Draw(); @@ -226,6 +226,45 @@ void GuiButton::Update(GuiTrigger * t) } } + if(this->IsDraggable()) + { + bool held = false; + + for(int i=0; i<2; i++) + { + if(trigger[i] && (trigger[i]->chan == -1 || trigger[i]->chan == t->chan)) + { + // higher 16 bits only (wiimote) + s32 wm_btns = t->wpad.btns_h << 16; + s32 wm_btns_trig = trigger[i]->wpad.btns_h << 16; + + // lower 16 bits only (classic controller) + s32 cc_btns = t->wpad.btns_h >> 16; + s32 cc_btns_trig = trigger[i]->wpad.btns_h >> 16; + + if( + (t->wpad.btns_h > 0 && + wm_btns == wm_btns_trig || + (cc_btns == cc_btns_trig && t->wpad.exp.type == EXP_CLASSIC)) || + (t->pad.btns_h == trigger[i]->pad.btns_h && t->pad.btns_h > 0)) + { + if(trigger[i]->type == TRIGGER_HELD) + held = true; + } + + if(!held && state == STATE_HELD && stateChan == t->chan) + { + state = STATE_DEFAULT; + } + else if(held && state == STATE_SELECTED) + { + state = STATE_HELD; + stateChan = t->chan; // record which controller is holding the button + } + } + } + } + if(updateCB) updateCB(this); } diff --git a/source/ngc/gui/gui_element.cpp b/source/ngc/gui/gui_element.cpp index 1a507be..87d030e 100644 --- a/source/ngc/gui/gui_element.cpp +++ b/source/ngc/gui/gui_element.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_element.cpp * @@ -17,17 +17,23 @@ GuiElement::GuiElement() { xoffset = 0; yoffset = 0; + xmin = 0; + xmax = 0; + ymin = 0; + ymax = 0; width = 0; height = 0; alpha = 255; scale = 1; state = STATE_DEFAULT; + stateChan = -1; trigger[0] = NULL; trigger[1] = NULL; parentElement = NULL; rumble = true; selectable = false; clickable = false; + draggable = false; visible = true; focus = -1; // cannot be focused updateCB = NULL; @@ -128,6 +134,46 @@ int GuiElement::GetTop() return y + yoffset; } +void GuiElement::SetMinX(int x) +{ + xmin = x; +} + +int GuiElement::GetMinX() +{ + return xmin; +} + +void GuiElement::SetMaxX(int x) +{ + xmax = x; +} + +int GuiElement::GetMaxX() +{ + return xmax; +} + +void GuiElement::SetMinY(int y) +{ + ymin = y; +} + +int GuiElement::GetMinY() +{ + return ymin; +} + +void GuiElement::SetMaxY(int y) +{ + ymax = y; +} + +int GuiElement::GetMaxY() +{ + return ymax; +} + /** * Get the width of the GuiElement. * @see SetWidth() @@ -243,6 +289,11 @@ void GuiElement::SetSelectable(bool s) selectable = s; } +void GuiElement::SetDraggable(bool d) +{ + draggable = d; +} + bool GuiElement::IsSelectable() { if(state == STATE_DISABLED || state == STATE_CLICKED) @@ -253,12 +304,22 @@ bool GuiElement::IsSelectable() bool GuiElement::IsClickable() { - if(state == STATE_DISABLED || state == STATE_CLICKED) + if(state == STATE_DISABLED || + state == STATE_CLICKED || + state == STATE_HELD) return false; else return clickable; } +bool GuiElement::IsDraggable() +{ + if(state == STATE_DISABLED) + return false; + else + return draggable; +} + void GuiElement::SetFocus(int f) { focus = f; diff --git a/source/ngc/gui/gui_filebrowser.cpp b/source/ngc/gui/gui_filebrowser.cpp index 5735b6d..2f6a588 100644 --- a/source/ngc/gui/gui_filebrowser.cpp +++ b/source/ngc/gui/gui_filebrowser.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_filebrowser.cpp * @@ -29,6 +29,12 @@ GuiFileBrowser::GuiFileBrowser(int w, int h) else trigA->SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + trigHeldA = new GuiTrigger; + if(GCSettings.WiimoteOrientation) + trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + else + trigHeldA->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + btnSoundOver = new GuiSound(button_over_pcm, button_over_pcm_size, SOUND_PCM); btnSoundClick = new GuiSound(button_click_pcm, button_click_pcm_size, SOUND_PCM); @@ -84,7 +90,12 @@ GuiFileBrowser::GuiFileBrowser(int w, int h) scrollbarBoxBtn->SetImage(scrollbarBoxImg); scrollbarBoxBtn->SetImageOver(scrollbarBoxOverImg); scrollbarBoxBtn->SetAlignment(ALIGN_RIGHT, ALIGN_TOP); + scrollbarBoxBtn->SetMinY(0); + scrollbarBoxBtn->SetMaxY(304); scrollbarBoxBtn->SetSelectable(false); + scrollbarBoxBtn->SetClickable(false); + scrollbarBoxBtn->SetDraggable(true); + scrollbarBoxBtn->SetTrigger(trigHeldA); for(int i=0; iSetPosition(0,position+36); arrowUpBtn->Update(t); arrowDownBtn->Update(t); scrollbarBoxBtn->Update(t); + if(scrollbarBoxBtn->GetState() == STATE_HELD) + { + // move the file listing to respond to wiimote cursor movement + if(t->wpad.ir.valid) + { + scrollbarBoxBtn->SetPosition(0,0); + position = t->wpad.ir.y - 60 - scrollbarBoxBtn->GetTop(); + + if(position > scrollbarBoxBtn->GetMinY() && + position < scrollbarBoxBtn->GetMaxY()) + { + scrollbarBoxBtn->SetPosition(0, position); + browser.pageIndex = (position * browser.numEntries)/136.0 - selectedItem; + + if(browser.pageIndex <= 0) + { + browser.pageIndex = 0; + selectedItem = 0; + } + else if(browser.pageIndex+PAGESIZE >= browser.numEntries) + { + browser.pageIndex = browser.numEntries-PAGESIZE; + selectedItem = PAGESIZE-1; + } + listChanged = true; + } + } + } + // pad/joystick navigation if(!focus) { diff --git a/source/ngc/gui/gui_image.cpp b/source/ngc/gui/gui_image.cpp index 17ab67d..d976f27 100644 --- a/source/ngc/gui/gui_image.cpp +++ b/source/ngc/gui/gui_image.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_image.cpp * diff --git a/source/ngc/gui/gui_imagedata.cpp b/source/ngc/gui/gui_imagedata.cpp index f8b34ae..6781be8 100644 --- a/source/ngc/gui/gui_imagedata.cpp +++ b/source/ngc/gui/gui_imagedata.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_imagedata.cpp * diff --git a/source/ngc/gui/gui_keyboard.cpp b/source/ngc/gui/gui_keyboard.cpp index 7c49b08..b792e99 100644 --- a/source/ngc/gui/gui_keyboard.cpp +++ b/source/ngc/gui/gui_keyboard.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_keyboard.cpp * diff --git a/source/ngc/gui/gui_optionbrowser.cpp b/source/ngc/gui/gui_optionbrowser.cpp index bd1275a..1c220a0 100644 --- a/source/ngc/gui/gui_optionbrowser.cpp +++ b/source/ngc/gui/gui_optionbrowser.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_optionbrowser.cpp * diff --git a/source/ngc/gui/gui_savebrowser.cpp b/source/ngc/gui/gui_savebrowser.cpp index 4baf772..d3a8dc7 100644 --- a/source/ngc/gui/gui_savebrowser.cpp +++ b/source/ngc/gui/gui_savebrowser.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_savebrowser.cpp * diff --git a/source/ngc/gui/gui_sound.cpp b/source/ngc/gui/gui_sound.cpp index 881cc07..61025a6 100644 --- a/source/ngc/gui/gui_sound.cpp +++ b/source/ngc/gui/gui_sound.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_sound.cpp * diff --git a/source/ngc/gui/gui_text.cpp b/source/ngc/gui/gui_text.cpp index 6caaf10..f3254a3 100644 --- a/source/ngc/gui/gui_text.cpp +++ b/source/ngc/gui/gui_text.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_text.cpp * diff --git a/source/ngc/gui/gui_trigger.cpp b/source/ngc/gui/gui_trigger.cpp index 648c50d..1a14c97 100644 --- a/source/ngc/gui/gui_trigger.cpp +++ b/source/ngc/gui/gui_trigger.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_trigger.cpp * @@ -42,6 +42,19 @@ void GuiTrigger::SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns) pad.btns_d = gcbtns; } +/** + * Sets a held trigger. Requires: + * - Element is selected + * - Trigger button is pressed and held + */ +void GuiTrigger::SetHeldTrigger(s32 ch, u32 wiibtns, u16 gcbtns) +{ + type = TRIGGER_HELD; + chan = ch; + wpad.btns_h = wiibtns; + pad.btns_h = gcbtns; +} + /** * Sets a button trigger. Requires: * - Trigger button is pressed diff --git a/source/ngc/gui/gui_window.cpp b/source/ngc/gui/gui_window.cpp index 64d16d0..6de39ad 100644 --- a/source/ngc/gui/gui_window.cpp +++ b/source/ngc/gui/gui_window.cpp @@ -1,7 +1,7 @@ /**************************************************************************** - * Snes9x 1.51 Nintendo Wii/Gamecube Port + * libwiigui * - * Tantric February 2009 + * Tantric 2009 * * gui_window.cpp * diff --git a/source/ngc/input.h b/source/ngc/input.h index 123c8f9..f57652e 100644 --- a/source/ngc/input.h +++ b/source/ngc/input.h @@ -24,6 +24,7 @@ enum { TRIGGER_SIMPLE, + TRIGGER_HELD, TRIGGER_BUTTON_ONLY, TRIGGER_BUTTON_ONLY_IN_FOCUS }; @@ -46,6 +47,7 @@ class GuiTrigger GuiTrigger(); ~GuiTrigger(); void SetSimpleTrigger(s32 ch, u32 wiibtns, u16 gcbtns); + void SetHeldTrigger(s32 ch, u32 wiibtns, u16 gcbtns); void SetButtonOnlyTrigger(s32 ch, u32 wiibtns, u16 gcbtns); void SetButtonOnlyInFocusTrigger(s32 ch, u32 wiibtns, u16 gcbtns); s8 WPAD_Stick(u8 right, int axis);