mirror of
				https://gitlab.com/Nanolx/homebrewfilter.git
				synced 2025-10-31 13:16:14 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			457 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			457 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /***************************************************************************
 | |
|  * Copyright (C) 2010
 | |
|  * by Dimok
 | |
|  *
 | |
|  * Copyright (C) 2010
 | |
|  * by dude
 | |
|  *
 | |
|  * This software is provided 'as-is', without any express or implied
 | |
|  * warranty. In no event will the authors be held liable for any
 | |
|  * damages arising from the use of this software.
 | |
|  *
 | |
|  * Permission is granted to anyone to use this software for any
 | |
|  * purpose, including commercial applications, and to alter it and
 | |
|  * redistribute it freely, subject to the following restrictions:
 | |
|  *
 | |
|  * 1. The origin of this software must not be misrepresented; you
 | |
|  * must not claim that you wrote the original software. If you use
 | |
|  * this software in a product, an acknowledgment in the product
 | |
|  * documentation would be appreciated but is not required.
 | |
|  *
 | |
|  * 2. Altered source versions must be plainly marked as such, and
 | |
|  * must not be misrepresented as being the original software.
 | |
|  *
 | |
|  * 3. This notice may not be removed or altered from any source
 | |
|  * distribution.
 | |
|  *
 | |
|  * PopUpMenu.cpp
 | |
|  *
 | |
|  * for WiiXplorer 2010
 | |
|  ***************************************************************************/
 | |
| 
 | |
| #include "PopUpMenu.h"
 | |
| //#include "Controls/MainWindow.h"
 | |
| #include "main.h"
 | |
| 
 | |
| /*** Extern functions ***/
 | |
| extern void ResumeGui();
 | |
| extern void HaltGui();
 | |
| 
 | |
| const int ButtonX = 20;
 | |
| const u32 ButtonHeight = 32;
 | |
| const u32 MaxVisible = 10;
 | |
| 
 | |
| PopUpMenu::PopUpMenu(int x, int y)
 | |
|     :GuiWindow(0, 0)
 | |
| {
 | |
| 	choice = -1;
 | |
| 	width = 0;
 | |
| 	height = 0;
 | |
| 	maxTxtWidth = 0;
 | |
| 	scrollIndex = 0;
 | |
| 	ScrollState = 0;
 | |
| 	hasIcons = false;
 | |
| 	hasSubmenus = false;
 | |
| 
 | |
| 	PopUpMenuUpper = Resources::GetImageData(startmenu_top_png, startmenu_top_png_size);
 | |
| //	PopUpMenuClick = Resources::GetSound(button_click_wav, button_click_wav_size);
 | |
| 	PopUpMenuMiddle = Resources::GetImageData(startmenu_png, startmenu_png_size);
 | |
| 	PopUpMenuLower = Resources::GetImageData(startmenu_top_png, startmenu_top_png_size);
 | |
| 	PopUpMenuSelect = Resources::GetImageData(menu_selection_png, menu_selection_png_size);
 | |
| 	PopUpMenuScrollUp = Resources::GetImageData(scrollbar_arrowup_png, scrollbar_arrowup_png_size);
 | |
| 	PopUpMenuScrollDown = Resources::GetImageData(scrollbar_arrowdown_png, scrollbar_arrowdown_png_size);
 | |
| 	PopUpMenuExpand = Resources::GetImageData(apps_plus_hover_png, apps_plus_hover_png_size);
 | |
| /*
 | |
| 	GuiImageData PopUpMenuUpper(Theme.startmenu_top);
 | |
| 	GuiImageData PopUpMenuMiddle(Theme.startmenu);
 | |
| 	GuiImageData PopUpMenuLower(Theme.startmenu_top);
 | |
| 	GuiImageData PopUpMenuSelect(Theme.menu_selection);
 | |
| 	GuiImageData PopUpMenuScrollUp(Theme.scrollbar_arrowup);
 | |
| 	GuiImageData PopUpMenuScrollDown(Theme.scrollbar_arrowdown);
 | |
| 	GuiImageData PopUpMenuExpand(Theme.apps_plus_hover);
 | |
| */
 | |
| 	PopUpMenuUpperImg = new GuiImage(PopUpMenuUpper);
 | |
| 	PopUpMenuMiddleImg = new GuiImage(PopUpMenuMiddle);
 | |
| 	PopUpMenuLowerImg = new GuiImage(PopUpMenuLower);
 | |
| 	PopUpMenuScrollUpImg = new GuiImage(PopUpMenuScrollUp);
 | |
| 	PopUpMenuScrollUpImg->SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
 | |
| 	PopUpMenuScrollDownImg = new GuiImage(PopUpMenuScrollDown);
 | |
| 	PopUpMenuScrollDownImg->SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE);
 | |
| 
 | |
| 	trigA = new SimpleGuiTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
 | |
| 	trigAHeld = new GuiTrigger();
 | |
| 	trigB = new GuiTrigger();
 | |
| 	trigUp = new GuiTrigger();
 | |
| 	trigDown = new GuiTrigger();
 | |
| 	trigHome = new GuiTrigger();
 | |
| 	trigB->SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B);
 | |
| 	trigAHeld->SetHeldTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A);
 | |
| 	trigUp->SetButtonOnlyHeldTrigger(-1, WPAD_BUTTON_UP | WPAD_CLASSIC_BUTTON_UP, PAD_BUTTON_UP);
 | |
| 	trigDown->SetButtonOnlyHeldTrigger(-1, WPAD_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_DOWN, PAD_BUTTON_DOWN);
 | |
| //	trigHome->SetButtonOnlyTrigger(-1, WiiControls.HomeButton | ClassicControls.HomeButton << 16, GCControls.HomeButton);
 | |
| 
 | |
| 	NoBtn = new GuiButton(screenwidth, screenheight);
 | |
| 	NoBtn->SetPosition(-x, -y);
 | |
| 	NoBtn->SetTrigger(trigA);
 | |
| 	NoBtn->SetTrigger(trigB);
 | |
| //	NoBtn->Clicked.connect(this, &PopUpMenu::OnClick);
 | |
| 
 | |
| //	HomeBtn = new GuiButton(0, 0);
 | |
| //	HomeBtn->SetTrigger(trigHome);
 | |
| //	HomeBtn->Clicked.connect(this, &PopUpMenu::OnClick);
 | |
| 
 | |
| 	ScrollUpBtn = new GuiButton(PopUpMenuUpperImg->GetWidth(), PopUpMenuScrollUpImg->GetHeight()+5);
 | |
| 	ScrollUpBtn->SetImage(PopUpMenuScrollUpImg);
 | |
| 	ScrollUpBtn->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
 | |
| 	ScrollUpBtn->SetTrigger(trigAHeld);
 | |
| 	ScrollUpBtn->SetVisible(false);
 | |
| 	ScrollUpBtn->SetState(STATE_DISABLED);
 | |
| 	ScrollUpBtn->SetTrigger(trigUp);
 | |
| 	ScrollUpBtn->SetHoldable(true);
 | |
| //	ScrollUpBtn->Held.connect(this, &PopUpMenu::OnScrollUp);
 | |
| 
 | |
| 	ScrollDownBtn = new GuiButton(PopUpMenuLowerImg->GetWidth(), PopUpMenuScrollDownImg->GetHeight()+5);
 | |
| 	ScrollDownBtn->SetImage(PopUpMenuScrollDownImg);
 | |
| 	ScrollDownBtn->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
 | |
| 	ScrollDownBtn->SetTrigger(trigAHeld);
 | |
| 	ScrollDownBtn->SetVisible(false);
 | |
| 	ScrollDownBtn->SetState(STATE_DISABLED);
 | |
| 	ScrollDownBtn->SetTrigger(trigDown);
 | |
| 	ScrollDownBtn->SetHoldable(true);
 | |
| //	ScrollDownBtn->Held.connect(this, &PopUpMenu::OnScrollDown);
 | |
| 
 | |
| 	Append(PopUpMenuUpperImg);
 | |
| 	Append(PopUpMenuMiddleImg);
 | |
| 	Append(PopUpMenuLowerImg);
 | |
| 	Append(NoBtn);
 | |
| //	Append(HomeBtn);
 | |
| 	Append(ScrollUpBtn);
 | |
| 	Append(ScrollDownBtn);
 | |
| 
 | |
| 	xpos = x;
 | |
| 	ypos = y;
 | |
| }
 | |
| 
 | |
| PopUpMenu::~PopUpMenu()
 | |
| {
 | |
| 	HaltGui();
 | |
| 	if(parentElement)
 | |
| 		((GuiWindow *) parentElement)->Remove(this);
 | |
| 
 | |
| 	RemoveAll();
 | |
| 
 | |
| 	Resources::Remove(PopUpMenuMiddle);
 | |
| 	Resources::Remove(PopUpMenuUpper);
 | |
| 	Resources::Remove(PopUpMenuLower);
 | |
| 	Resources::Remove(PopUpMenuSelect);
 | |
| 	Resources::Remove(PopUpMenuScrollUp);
 | |
| 	Resources::Remove(PopUpMenuScrollDown);
 | |
| 	Resources::Remove(PopUpMenuExpand);
 | |
| 	Resources::Remove(PopUpMenuClick);
 | |
| 
 | |
| 	for (u32 i = 0; i < Item.size(); i++)
 | |
| 	{
 | |
| 		delete Item[i].ButtonMenuSelect;
 | |
| 		delete Item[i].Button;
 | |
| 		delete Item[i].ButtonTxt;
 | |
| 		delete Item[i].ButtonTxtOver;
 | |
| 
 | |
| 		if (Item[i].Icon)
 | |
| 		{
 | |
| 			Resources::Remove(Item[i].Icon);
 | |
| 			delete Item[i].IconImg;
 | |
| 		}
 | |
| 
 | |
| 		if (Item[i].ExpandImg)
 | |
| 			delete Item[i].ExpandImg;
 | |
| 	}
 | |
| 
 | |
| 	Item.clear();
 | |
| 
 | |
| 	delete PopUpMenuMiddleImg;
 | |
| 	delete PopUpMenuUpperImg;
 | |
| 	delete PopUpMenuLowerImg;
 | |
| 	delete PopUpMenuScrollUpImg;
 | |
| 	delete PopUpMenuScrollDownImg;
 | |
| 
 | |
| 	delete ScrollUpBtn;
 | |
| 	delete ScrollDownBtn;
 | |
| 	delete NoBtn;
 | |
| 	delete HomeBtn;
 | |
| 
 | |
| 	delete trigA;
 | |
| 	delete trigAHeld;
 | |
| 	delete trigB;
 | |
| 	delete trigUp;
 | |
| 	delete trigDown;
 | |
| 	delete trigHome;
 | |
| 
 | |
| 	ResumeGui();
 | |
| }
 | |
| 
 | |
| void PopUpMenu::AddItem(const char *text, const u8 *icon, u32 icon_size, bool submenu)
 | |
| {
 | |
| 	Items item;
 | |
| 
 | |
| 	item.ButtonTxt = new GuiText(text, 24, (GXColor){0, 0, 0, 255});
 | |
| 	item.ButtonTxtOver = new GuiText(text, 24, (GXColor){28, 32, 190, 255});
 | |
| 	item.Button = new GuiButton(0, 0);
 | |
| 	item.ButtonMenuSelect = new GuiImage(PopUpMenuSelect);
 | |
| 	item.ButtonTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
 | |
| 	item.ButtonTxtOver->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
 | |
| 	item.Button->SetLabel(item.ButtonTxt);
 | |
| 	item.Button->SetLabelOver(item.ButtonTxtOver);
 | |
| 	item.Button->SetSoundClick(PopUpMenuClick);
 | |
| 	item.Button->SetImageOver(item.ButtonMenuSelect);
 | |
| 	item.Button->SetTrigger(trigA);
 | |
| 	item.Button->SetAlignment(ALIGN_LEFT, ALIGN_TOP);
 | |
| //	item.Button->Clicked.connect(this, &PopUpMenu::OnClick);
 | |
| 
 | |
| 	Append(item.Button);
 | |
| 
 | |
| 	if (icon)
 | |
| 	{
 | |
| 		item.Icon = Resources::GetImageData(icon, icon_size);
 | |
| 
 | |
| 		item.IconImg = new GuiImage(item.Icon);
 | |
| 		item.IconImg->SetPosition(ButtonX, (Item.size()+1)*ButtonHeight-18);
 | |
| 		item.IconImg->SetScale(0.8);
 | |
| 
 | |
| 		hasIcons = true;
 | |
| 
 | |
| 		Append(item.IconImg);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		item.Icon = NULL;
 | |
| 		item.IconImg = NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (submenu)
 | |
| 	{
 | |
| 		item.ExpandImg = new GuiImage(PopUpMenuExpand);
 | |
| 
 | |
| 		hasSubmenus = true;
 | |
| 
 | |
| 		Append(item.ExpandImg);
 | |
| 	}
 | |
| 	else
 | |
| 		item.ExpandImg = NULL;
 | |
| 
 | |
| 	if (maxTxtWidth < item.ButtonTxt->GetTextWidth())
 | |
| 		maxTxtWidth = item.ButtonTxt->GetTextWidth();
 | |
| 
 | |
| 	Item.push_back(item);
 | |
| }
 | |
| 
 | |
| void PopUpMenu::Finish()
 | |
| {
 | |
| 	u32 x = xpos;
 | |
| 	u32 y = ypos;
 | |
| 	u32 middleheight = ButtonHeight*Item.size();
 | |
| 	int leftmargin = (hasIcons ? ButtonX+40 : ButtonX);
 | |
| 	int rightmargin = (hasSubmenus ? 40 : 20);
 | |
| 	float scale = 1.0f;
 | |
|     int ButtonsOffset = 0;
 | |
| 
 | |
| 	if(Item.size() > MaxVisible)
 | |
| 	{
 | |
| 		ScrollDownBtn->SetVisible(true);
 | |
| 		ScrollDownBtn->SetState(STATE_DEFAULT);
 | |
| 
 | |
| 		middleheight = ButtonHeight*MaxVisible;
 | |
| 
 | |
|         middleheight += PopUpMenuScrollUpImg->GetHeight()+PopUpMenuScrollDownImg->GetHeight()-10;
 | |
|         ButtonsOffset += PopUpMenuScrollUpImg->GetHeight();
 | |
| 
 | |
| 		for (u32 i = MaxVisible; i < Item.size(); i++)
 | |
| 		{
 | |
| 			Item[i].Button->SetVisible(false);
 | |
| 			Item[i].Button->SetState(STATE_DISABLED);
 | |
| 
 | |
| 			if (Item[i].IconImg)
 | |
| 				Item[i].IconImg->SetVisible(false);
 | |
| 
 | |
| 			if (Item[i].ExpandImg)
 | |
| 				Item[i].ExpandImg->SetVisible(false);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	width  = maxTxtWidth+leftmargin+rightmargin;
 | |
| 	height = PopUpMenuLowerImg->GetHeight()+middleheight+PopUpMenuUpperImg->GetHeight();
 | |
| 
 | |
| 	PopUpMenuMiddleImg->SetTileVertical(middleheight/PopUpMenuMiddleImg->GetHeight());
 | |
| 
 | |
| 	if (width > PopUpMenuMiddleImg->GetWidth())
 | |
| 		scale = 1.0f * width / PopUpMenuMiddleImg->GetWidth();
 | |
| 
 | |
| 	PopUpMenuUpperImg->SetScaleX(scale);
 | |
| 	PopUpMenuMiddleImg->SetScaleX(scale);
 | |
| 	PopUpMenuLowerImg->SetScaleX(scale);
 | |
| 
 | |
| 	u32 scaledX = (scale-1)*PopUpMenuMiddleImg->GetWidth()/2;
 | |
| 
 | |
| 	PopUpMenuUpperImg->SetPosition(scaledX, 0);
 | |
| 	PopUpMenuMiddleImg->SetPosition(scaledX, PopUpMenuUpperImg->GetHeight());
 | |
| 	PopUpMenuLowerImg->SetPosition(scaledX, PopUpMenuUpperImg->GetHeight()+middleheight);
 | |
| 
 | |
| 	ScrollUpBtn->SetPosition(width/2-ScrollUpBtn->GetWidth()/2, 10);
 | |
| 	ScrollDownBtn->SetPosition(width/2-ScrollDownBtn->GetWidth()/2, PopUpMenuLowerImg->GetTop()-ScrollDownBtn->GetHeight()/2);
 | |
| 
 | |
| 	if (x + width + 15 > (u32)screenwidth)
 | |
| 		x = screenwidth - width - 15;
 | |
| 
 | |
| 	if (y + height + 25 > (u32)screenheight)
 | |
| 		y = screenheight - height - 35;
 | |
| 
 | |
| 	for (u32 i = 0; i < Item.size(); i++)
 | |
| 	{
 | |
| 		Item[i].Button->SetSize(maxTxtWidth, ButtonHeight);
 | |
| 		Item[i].Button->SetPosition(leftmargin, i*ButtonHeight+20+ButtonsOffset);
 | |
| 
 | |
| 		Item[i].ButtonMenuSelect->SetScaleX(scale);
 | |
| 		Item[i].ButtonMenuSelect->SetPosition(scaledX, -4);
 | |
| 
 | |
| 		if (Item[i].ExpandImg)
 | |
| 			Item[i].ExpandImg->SetPosition(width-32, i*ButtonHeight+22+ButtonsOffset);
 | |
| 	}
 | |
| 
 | |
| 	SetPosition(x, y);
 | |
| }
 | |
| 
 | |
| void PopUpMenu::Update(GuiTrigger * t)
 | |
| {
 | |
| 
 | |
| // { GuiWindow::Update(t); ++ScrollState; }
 | |
| 
 | |
| 
 | |
| 
 | |
| 	if(_elements.size() == 0 /*|| (state == STATE_DISABLED && parentElement) || (state == STATE_DISABLED2 && parentElement)*/)
 | |
| 		return;
 | |
| 
 | |
| 	for (u8 i = 0; i < _elements.size(); i++)
 | |
| 	{
 | |
| 		try	{ _elements.at(i)->Update(t); }
 | |
| 		catch (const std::exception& e) { }
 | |
| 	}
 | |
| 
 | |
| 	for (u32 i = 0; i < Item.size(); i++)
 | |
| 	{
 | |
| 		if(Item[i].Button->GetState() == STATE_CLICKED)
 | |
| 		{
 | |
| 			OnClick(Item[i].Button);
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if(NoBtn->GetState() == STATE_CLICKED)
 | |
| 		OnClick(NoBtn);
 | |
| }
 | |
| 
 | |
| int PopUpMenu::GetChoice()
 | |
| {
 | |
| 	return choice;
 | |
| }
 | |
| 
 | |
| void PopUpMenu::OnClick(GuiElement *sender)
 | |
| {
 | |
| 	sender->ResetState();
 | |
| 	//TODO add the functions instead of the link
 | |
| 	if (sender == NoBtn || sender == HomeBtn)
 | |
| 	{
 | |
| 		choice = -10;
 | |
| 		return;
 | |
| 	}
 | |
| 
 | |
| 	for (u32 i = 0; i < Item.size(); i++)
 | |
| 	{
 | |
| 		if(sender == Item[i].Button)
 | |
| 		{
 | |
| 			choice = i;
 | |
| 			break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void PopUpMenu::OnScrollUp(GuiElement *sender UNUSED, int pointer UNUSED, POINT p UNUSED)
 | |
| {
 | |
|  //   if(ScrollState < (u32) Settings.ScrollSpeed)
 | |
|     if(ScrollState < (u32) 5)
 | |
|         return;
 | |
| 
 | |
| 	Scroll(UP);
 | |
| 
 | |
| 	ScrollState = 0;
 | |
| }
 | |
| 
 | |
| void PopUpMenu::OnScrollDown(GuiElement *sender UNUSED, int pointer UNUSED, POINT p UNUSED)
 | |
| {
 | |
|  //   if(ScrollState < (u32) Settings.ScrollSpeed)
 | |
|     if(ScrollState < (u32) 5)
 | |
|         return;
 | |
| 
 | |
| 	Scroll(DOWN);
 | |
| 
 | |
| 	ScrollState = 0;
 | |
| }
 | |
| 
 | |
| void PopUpMenu::Scroll(int direction)
 | |
| {
 | |
| 	choice = -1;
 | |
| 	int step = ButtonHeight;
 | |
| 
 | |
| 	if (direction == UP)
 | |
| 	{
 | |
| 		if (scrollIndex < 1)
 | |
| 			return;
 | |
| 
 | |
| 		scrollIndex--;
 | |
| 		ScrollDownBtn->SetVisible(true);
 | |
| 		ScrollDownBtn->SetState(STATE_DEFAULT);
 | |
| 	}
 | |
| 	else
 | |
| 	{
 | |
| 		if (scrollIndex >= Item.size()-MaxVisible)
 | |
| 			return;
 | |
| 
 | |
| 		scrollIndex++;
 | |
| 		ScrollUpBtn->SetVisible(true);
 | |
| 		ScrollUpBtn->SetState(STATE_DEFAULT);
 | |
| 		step *= -1;
 | |
| 	}
 | |
| 
 | |
| 	for (u32 i = 0; i < Item.size(); i++)
 | |
| 	{
 | |
| 		bool visible = (i >= scrollIndex && i < scrollIndex+MaxVisible);
 | |
| 		int state = visible ? STATE_DEFAULT : STATE_DISABLED;
 | |
| 
 | |
| 		Item[i].Button->SetVisible(visible);
 | |
| 		Item[i].Button->SetPosition(Item[i].Button->GetLeft()-GetLeft(), Item[i].Button->GetTop()-GetTop()+step);
 | |
| 		Item[i].Button->SetState(state);
 | |
| 
 | |
| 		if (Item[i].IconImg)
 | |
| 		{
 | |
| 			Item[i].IconImg->SetVisible(visible);
 | |
| 			Item[i].IconImg->SetPosition(Item[i].IconImg->GetLeft()-GetLeft(), Item[i].IconImg->GetTop()-GetTop()+step);
 | |
| 		}
 | |
| 
 | |
| 		if (Item[i].ExpandImg)
 | |
| 		{
 | |
| 			Item[i].ExpandImg->SetVisible(visible);
 | |
| 			Item[i].ExpandImg->SetPosition(Item[i].ExpandImg->GetLeft()-GetLeft(), Item[i].ExpandImg->GetTop()-GetTop()+step);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	if (scrollIndex >= Item.size()-MaxVisible)
 | |
| 	{
 | |
| 		ScrollDownBtn->SetVisible(false);
 | |
| 		ScrollDownBtn->SetState(STATE_DISABLED);
 | |
| 	}
 | |
| 
 | |
| 	if (scrollIndex < 1)
 | |
| 	{
 | |
| 		ScrollUpBtn->SetVisible(false);
 | |
| 		ScrollUpBtn->SetState(STATE_DISABLED);
 | |
| 	}
 | |
| }
 | 
