2015-06-28 05:34:05 +00:00
// Copyright (c) 2013- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
2020-10-04 08:10:55 +00:00
# include "Common/System/Display.h"
2020-10-04 21:24:14 +00:00
# include "Common/Render/DrawBuffer.h"
# include "Common/Render/TextureAtlas.h"
2020-10-04 18:48:47 +00:00
# include "Common/UI/Context.h"
# include "Common/UI/View.h"
# include "Common/UI/ViewGroup.h"
2015-06-28 05:34:05 +00:00
2020-10-03 22:25:21 +00:00
# include "Common/Data/Text/I18n.h"
# include "Common/Data/Color/RGBAUtil.h"
# include "Common/Math/curves.h"
2020-08-15 18:53:08 +00:00
# include "Common/TimeUtil.h"
2020-09-29 10:19:22 +00:00
# include "Common/StringUtils.h"
# include "Core/Config.h"
2023-03-26 09:21:34 +00:00
# include "UI/CustomButtonMappingScreen.h"
2020-08-15 18:53:08 +00:00
2021-09-22 21:05:33 +00:00
class ButtonShapeScreen : public PopupScreen {
public :
ButtonShapeScreen ( std : : string title , int * setting ) : PopupScreen ( title ) , setting_ ( setting ) { }
void CreatePopupContents ( UI : : ViewGroup * parent ) override {
using namespace UI ;
2023-03-26 08:48:59 +00:00
using namespace CustomKeyData ;
2021-09-22 21:05:33 +00:00
ScrollView * scroll = new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT , 1.0f ) ) ;
LinearLayout * items = new LinearLayoutList ( ORIENT_VERTICAL ) ;
2023-03-26 08:48:59 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyShapes ) ; + + i ) {
Choice * c = items - > Add ( new Choice ( ImageID ( customKeyShapes [ i ] . l ) , 0.6f , customKeyShapes [ i ] . r * PI / 180 , customKeyShapes [ i ] . f ) ) ;
2021-09-22 21:05:33 +00:00
c - > OnClick . Add ( [ = ] ( UI : : EventParams & e ) {
* setting_ = i ;
TriggerFinish ( DR_OK ) ;
return UI : : EVENT_DONE ;
} ) ;
}
scroll - > Add ( items ) ;
parent - > Add ( scroll ) ;
}
2022-09-16 08:14:00 +00:00
const char * tag ( ) const override { return " ButtonShape " ; }
2021-09-22 21:05:33 +00:00
private :
int * setting_ ;
} ;
class ButtonIconScreen : public PopupScreen {
public :
ButtonIconScreen ( std : : string title , int * setting ) : PopupScreen ( title ) , setting_ ( setting ) { }
void CreatePopupContents ( UI : : ViewGroup * parent ) override {
using namespace UI ;
2023-03-26 08:48:59 +00:00
using namespace CustomKeyData ;
2021-09-22 21:05:33 +00:00
ScrollView * scroll = new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT , 1.0f ) ) ;
LinearLayout * items = new LinearLayoutList ( ORIENT_VERTICAL ) ;
2023-03-26 08:48:59 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyImages ) ; + + i ) {
Choice * c = items - > Add ( new Choice ( ImageID ( customKeyImages [ i ] . i ) , 1.0f , customKeyImages [ i ] . r * PI / 180 ) ) ;
2021-09-22 21:05:33 +00:00
c - > OnClick . Add ( [ = ] ( UI : : EventParams & e ) {
* setting_ = i ;
TriggerFinish ( DR_OK ) ;
return UI : : EVENT_DONE ;
} ) ;
}
scroll - > Add ( items ) ;
parent - > Add ( scroll ) ;
}
2022-09-16 08:14:00 +00:00
const char * tag ( ) const override { return " ButtonIcon " ; }
2021-09-22 21:05:33 +00:00
private :
int * setting_ ;
} ;
2021-03-04 09:37:35 +00:00
class ButtonPreview : public UI : : View {
public :
ButtonPreview ( ImageID bgImg , ImageID img , float rotationIcon , bool flipShape , float rotationShape , int x , int y )
: View ( new UI : : AnchorLayoutParams ( x , y , UI : : NONE , UI : : NONE , true ) ) , bgImg_ ( bgImg ) , img_ ( img ) , rotI_ ( rotationIcon ) ,
flipS_ ( flipShape ) , rotS_ ( rotationShape ) , x_ ( x ) , y_ ( y ) { }
void Draw ( UIContext & dc ) override {
float opacity = g_Config . iTouchButtonOpacity / 100.0f ;
uint32_t colorBg = colorAlpha ( g_Config . iTouchButtonStyle ! = 0 ? 0xFFFFFF : 0xc0b080 , opacity ) ;
uint32_t color = colorAlpha ( 0xFFFFFF , opacity ) ;
dc . Draw ( ) - > DrawImageRotated ( bgImg_ , x_ , y_ , 1.0f , rotS_ * PI / 180 , colorBg , flipS_ ) ;
dc . Draw ( ) - > DrawImageRotated ( img_ , x_ , y_ , 1.0f , rotI_ * PI / 180 , color , false ) ;
}
private :
int x_ ;
int y_ ;
float rotI_ ;
float rotS_ ;
bool flipS_ ;
ImageID bgImg_ ;
ImageID img_ ;
} ;
2023-03-26 09:22:54 +00:00
void CustomButtonMappingScreen : : CreateViews ( ) {
2015-06-28 05:34:05 +00:00
using namespace UI ;
2023-03-26 08:48:59 +00:00
using namespace CustomKeyData ;
2023-04-05 22:34:50 +00:00
auto co = GetI18NCategory ( I18NCat : : CONTROLS ) ;
auto mc = GetI18NCategory ( I18NCat : : MAPPABLECONTROLS ) ;
2015-06-28 05:34:05 +00:00
root_ = new LinearLayout ( ORIENT_VERTICAL ) ;
2021-03-04 09:37:35 +00:00
root_ - > Add ( new ItemHeader ( co - > T ( " Custom Key Setting " ) ) ) ;
2015-10-31 12:43:33 +00:00
LinearLayout * root__ = new LinearLayout ( ORIENT_HORIZONTAL , new LinearLayoutParams ( 1.0 ) ) ;
2015-06-28 05:34:05 +00:00
root_ - > Add ( root__ ) ;
LinearLayout * leftColumn = new LinearLayout ( ORIENT_VERTICAL , new LinearLayoutParams ( 120 , FILL_PARENT ) ) ;
2023-04-05 22:34:50 +00:00
auto di = GetI18NCategory ( I18NCat : : DIALOG ) ;
2015-06-28 05:34:05 +00:00
2021-03-04 09:37:35 +00:00
ConfigCustomButton * cfg = nullptr ;
bool * show = nullptr ;
2015-06-28 05:34:05 +00:00
memset ( array , 0 , sizeof ( array ) ) ;
2021-03-04 09:37:35 +00:00
switch ( id_ ) {
2015-06-28 05:34:05 +00:00
case 0 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton0 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom0 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton0 . key > > i ) & 0x01 ) ) ;
2015-06-28 05:34:05 +00:00
break ;
case 1 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton1 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom1 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton1 . key > > i ) & 0x01 ) ) ;
2015-06-28 05:34:05 +00:00
break ;
case 2 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton2 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom2 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton2 . key > > i ) & 0x01 ) ) ;
2015-06-28 05:34:05 +00:00
break ;
case 3 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton3 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom3 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton3 . key > > i ) & 0x01 ) ) ;
2015-06-28 05:34:05 +00:00
break ;
case 4 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton4 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom4 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton4 . key > > i ) & 0x01 ) ) ;
2021-03-04 09:37:35 +00:00
break ;
case 5 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton5 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom5 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton5 . key > > i ) & 0x01 ) ) ;
2021-03-04 09:37:35 +00:00
break ;
case 6 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton6 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom6 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton6 . key > > i ) & 0x01 ) ) ;
2021-03-04 09:37:35 +00:00
break ;
case 7 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton7 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom7 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton7 . key > > i ) & 0x01 ) ) ;
2021-03-04 09:37:35 +00:00
break ;
case 8 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton8 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom8 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton8 . key > > i ) & 0x01 ) ) ;
2021-03-04 09:37:35 +00:00
break ;
case 9 :
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton9 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom9 . show ;
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; i + + )
2023-03-26 09:21:34 +00:00
array [ i ] = ( 0x01 = = ( ( g_Config . CustomButton9 . key > > i ) & 0x01 ) ) ;
2015-06-28 05:34:05 +00:00
break ;
2020-03-03 21:19:32 +00:00
default :
// This shouldn't happen, let's just not crash.
2023-03-26 09:21:34 +00:00
cfg = & g_Config . CustomButton0 ;
2023-03-26 08:48:59 +00:00
show = & g_Config . touchCustom0 . show ;
2020-03-03 21:19:32 +00:00
break ;
2015-06-28 05:34:05 +00:00
}
2023-03-26 08:48:59 +00:00
leftColumn - > Add ( new ButtonPreview ( g_Config . iTouchButtonStyle = = 0 ? customKeyShapes [ cfg - > shape ] . i : customKeyShapes [ cfg - > shape ] . l ,
customKeyImages [ cfg - > image ] . i , customKeyImages [ cfg - > image ] . r , customKeyShapes [ cfg - > shape ] . f , customKeyShapes [ cfg - > shape ] . r , 62 , 82 ) ) ;
2015-06-28 05:34:05 +00:00
2021-03-04 09:37:35 +00:00
root__ - > Add ( leftColumn ) ;
rightScroll_ = new ScrollView ( ORIENT_VERTICAL , new LinearLayoutParams ( WRAP_CONTENT , WRAP_CONTENT , 1.0f ) ) ;
leftColumn - > Add ( new Spacer ( new LinearLayoutParams ( 1.0f ) ) ) ;
leftColumn - > Add ( new Choice ( di - > T ( " Back " ) ) ) - > OnClick . Handle < UIScreen > ( this , & UIScreen : : OnBack ) ;
root__ - > Add ( rightScroll_ ) ;
2015-06-28 05:34:05 +00:00
2021-03-04 09:37:35 +00:00
LinearLayout * vertLayout = new LinearLayout ( ORIENT_VERTICAL ) ;
rightScroll_ - > Add ( vertLayout ) ;
2021-09-22 07:16:49 +00:00
vertLayout - > Add ( new ItemHeader ( co - > T ( " Button style " ) ) ) ;
2021-03-04 09:37:35 +00:00
vertLayout - > Add ( new CheckBox ( show , co - > T ( " Visible " ) ) ) ;
2021-09-22 21:05:33 +00:00
Choice * icon = vertLayout - > Add ( new Choice ( co - > T ( " Icon " ) ) ) ;
2023-03-26 08:48:59 +00:00
icon - > SetIcon ( ImageID ( customKeyImages [ cfg - > image ] . i ) , 1.0f , customKeyImages [ cfg - > image ] . r * PI / 180 , false , false ) ; // Set right icon on the choice
2021-09-22 21:05:33 +00:00
icon - > OnClick . Add ( [ = ] ( UI : : EventParams & e ) {
auto iconScreen = new ButtonIconScreen ( co - > T ( " Icon " ) , & ( cfg - > image ) ) ;
if ( e . v )
iconScreen - > SetPopupOrigin ( e . v ) ;
screenManager ( ) - > push ( iconScreen ) ;
return UI : : EVENT_DONE ;
} ) ;
Choice * shape = vertLayout - > Add ( new Choice ( co - > T ( " Shape " ) ) ) ;
2023-03-26 08:48:59 +00:00
shape - > SetIcon ( ImageID ( customKeyShapes [ cfg - > shape ] . l ) , 0.6f , customKeyShapes [ cfg - > shape ] . r * PI / 180 , customKeyShapes [ cfg - > shape ] . f , false ) ; // Set right icon on the choice
2021-09-22 21:05:33 +00:00
shape - > OnClick . Add ( [ = ] ( UI : : EventParams & e ) {
auto shape = new ButtonShapeScreen ( co - > T ( " Shape " ) , & ( cfg - > shape ) ) ;
if ( e . v )
shape - > SetPopupOrigin ( e . v ) ;
screenManager ( ) - > push ( shape ) ;
return UI : : EVENT_DONE ;
} ) ;
2021-03-04 09:37:35 +00:00
vertLayout - > Add ( new ItemHeader ( co - > T ( " Button Binding " ) ) ) ;
vertLayout - > Add ( new CheckBox ( & ( cfg - > toggle ) , co - > T ( " Toggle mode " ) ) ) ;
2022-06-19 13:18:05 +00:00
vertLayout - > Add ( new CheckBox ( & ( cfg - > repeat ) , co - > T ( " Repeat mode " ) ) ) ;
2021-03-04 09:37:35 +00:00
const int cellSize = 400 ;
UI : : GridLayoutSettings gridsettings ( cellSize , 64 , 5 ) ;
gridsettings . fillCells = true ;
GridLayout * grid = vertLayout - > Add ( new GridLayout ( gridsettings , new LayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ) ;
2021-08-30 11:17:24 +00:00
// Button image and action are defined in GamepadEmu.h
2023-03-26 08:48:59 +00:00
for ( int i = 0 ; i < ARRAY_SIZE ( customKeyList ) ; + + i ) {
2015-06-28 05:34:05 +00:00
LinearLayout * row = new LinearLayout ( ORIENT_HORIZONTAL , new LinearLayoutParams ( FILL_PARENT , WRAP_CONTENT ) ) ;
row - > SetSpacing ( 0 ) ;
2021-03-04 09:37:35 +00:00
CheckBox * checkbox = new CheckBox ( & array [ i ] , " " , " " , new LinearLayoutParams ( 50 , WRAP_CONTENT ) ) ;
2015-06-28 05:34:05 +00:00
row - > Add ( checkbox ) ;
Choice * choice ;
2023-03-26 08:48:59 +00:00
if ( customKeyList [ i ] . i . isValid ( ) ) {
choice = new Choice ( customKeyList [ i ] . i , new LinearLayoutParams ( 1.0f ) ) ;
2021-03-04 09:37:35 +00:00
} else {
2023-03-26 08:48:59 +00:00
choice = new Choice ( mc - > T ( KeyMap : : GetPspButtonNameCharPointer ( customKeyList [ i ] . c ) ) , new LinearLayoutParams ( 1.0f ) ) ;
2015-06-28 05:34:05 +00:00
}
ChoiceEventHandler * choiceEventHandler = new ChoiceEventHandler ( checkbox ) ;
choice - > OnClick . Handle ( choiceEventHandler , & ChoiceEventHandler : : onChoiceClick ) ;
choice - > SetCentered ( true ) ;
row - > Add ( choice ) ;
grid - > Add ( row ) ;
}
}
2023-03-26 08:48:59 +00:00
static uint64_t arrayToInt ( const bool ary [ ARRAY_SIZE ( CustomKeyData : : customKeyList ) ] ) {
2021-03-04 09:37:35 +00:00
uint64_t value = 0 ;
2023-03-26 08:48:59 +00:00
for ( int i = ARRAY_SIZE ( CustomKeyData : : customKeyList ) - 1 ; i > = 0 ; i - - ) {
2015-06-28 05:34:05 +00:00
value | = ary [ i ] ? 1 : 0 ;
2021-03-04 09:37:35 +00:00
if ( i > 0 ) {
value = value < < 1 ;
}
2015-06-28 05:34:05 +00:00
}
2021-03-04 09:37:35 +00:00
return value ;
2015-06-28 05:34:05 +00:00
}
2023-03-26 09:22:54 +00:00
void CustomButtonMappingScreen : : saveArray ( ) {
2021-03-04 09:37:35 +00:00
switch ( id_ ) {
2015-06-28 05:34:05 +00:00
case 0 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton0 . key = arrayToInt ( array ) ;
2015-06-28 05:34:05 +00:00
break ;
case 1 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton1 . key = arrayToInt ( array ) ;
2015-06-28 05:34:05 +00:00
break ;
case 2 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton2 . key = arrayToInt ( array ) ;
2015-06-28 05:34:05 +00:00
break ;
case 3 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton3 . key = arrayToInt ( array ) ;
2015-06-28 05:34:05 +00:00
break ;
case 4 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton4 . key = arrayToInt ( array ) ;
2021-03-04 09:37:35 +00:00
break ;
case 5 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton5 . key = arrayToInt ( array ) ;
2021-03-04 09:37:35 +00:00
break ;
case 6 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton6 . key = arrayToInt ( array ) ;
2021-03-04 09:37:35 +00:00
break ;
case 7 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton7 . key = arrayToInt ( array ) ;
2021-03-04 09:37:35 +00:00
break ;
case 8 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton8 . key = arrayToInt ( array ) ;
2021-03-04 09:37:35 +00:00
break ;
case 9 :
2023-03-26 09:21:34 +00:00
g_Config . CustomButton9 . key = arrayToInt ( array ) ;
2015-06-28 05:34:05 +00:00
break ;
}
2021-03-04 09:37:35 +00:00
}
2023-03-26 09:22:54 +00:00
void CustomButtonMappingScreen : : dialogFinished ( const Screen * dialog , DialogResult result ) {
2021-09-22 21:05:33 +00:00
saveArray ( ) ;
RecreateViews ( ) ;
}
2023-03-26 09:22:54 +00:00
void CustomButtonMappingScreen : : onFinish ( DialogResult result ) {
2021-03-04 09:37:35 +00:00
saveArray ( ) ;
2023-03-26 09:22:54 +00:00
g_Config . Save ( " CustomButtonMappingScreen::onFinish " ) ;
2015-06-28 05:34:05 +00:00
}
2023-03-26 09:22:54 +00:00
UI : : EventReturn CustomButtonMappingScreen : : ChoiceEventHandler : : onChoiceClick ( UI : : EventParams & e ) {
2015-06-28 05:34:05 +00:00
checkbox_ - > Toggle ( ) ;
return UI : : EVENT_DONE ;
} ;