2014-06-25 16:29:58 +00:00
# include "guis/GuiMetaDataEd.h"
# include "Renderer.h"
# include "Log.h"
# include "components/AsyncReqComponent.h"
# include "Settings.h"
# include "views/ViewController.h"
# include "guis/GuiGameScraper.h"
# include "guis/GuiMsgBox.h"
# include <boost/filesystem.hpp>
# include "components/TextEditComponent.h"
# include "components/DateTimeComponent.h"
# include "components/RatingComponent.h"
2017-06-12 16:38:59 +00:00
# include "components/SwitchComponent.h"
2014-06-25 16:29:58 +00:00
# include "guis/GuiTextEditPopup.h"
using namespace Eigen ;
2017-05-18 10:16:57 +00:00
GuiMetaDataEd : : GuiMetaDataEd ( Window * window , MetaDataList * md , const std : : vector < MetaDataDecl > & mdd , ScraperSearchParams scraperParams ,
const std : : string & header , std : : function < void ( ) > saveCallback , std : : function < void ( ) > deleteFunc ) : GuiComponent ( window ) ,
mScraperParams ( scraperParams ) ,
2014-06-25 16:29:58 +00:00
2017-05-18 10:16:57 +00:00
mBackground ( window , " :/frame.png " ) ,
2014-06-25 16:29:58 +00:00
mGrid ( window , Vector2i ( 1 , 3 ) ) ,
2017-05-18 10:16:57 +00:00
mMetaDataDecl ( mdd ) ,
mMetaData ( md ) ,
2014-06-25 16:29:58 +00:00
mSavedCallback ( saveCallback ) , mDeleteFunc ( deleteFunc )
{
addChild ( & mBackground ) ;
addChild ( & mGrid ) ;
mHeaderGrid = std : : make_shared < ComponentGrid > ( mWindow , Vector2i ( 1 , 5 ) ) ;
2017-05-18 10:16:57 +00:00
2014-06-25 16:29:58 +00:00
mTitle = std : : make_shared < TextComponent > ( mWindow , " EDIT METADATA " , Font : : get ( FONT_SIZE_LARGE ) , 0x555555FF , ALIGN_CENTER ) ;
2017-05-18 10:16:57 +00:00
mSubtitle = std : : make_shared < TextComponent > ( mWindow , strToUpper ( scraperParams . game - > getPath ( ) . filename ( ) . generic_string ( ) ) ,
2014-06-25 16:29:58 +00:00
Font : : get ( FONT_SIZE_SMALL ) , 0x777777FF , ALIGN_CENTER ) ;
mHeaderGrid - > setEntry ( mTitle , Vector2i ( 0 , 1 ) , false , true ) ;
mHeaderGrid - > setEntry ( mSubtitle , Vector2i ( 0 , 3 ) , false , true ) ;
mGrid . setEntry ( mHeaderGrid , Vector2i ( 0 , 0 ) , false , true ) ;
mList = std : : make_shared < ComponentList > ( mWindow ) ;
mGrid . setEntry ( mList , Vector2i ( 0 , 1 ) , true , true ) ;
// populate list
for ( auto iter = mdd . begin ( ) ; iter ! = mdd . end ( ) ; iter + + )
{
std : : shared_ptr < GuiComponent > ed ;
// don't add statistics
if ( iter - > isStatistic )
continue ;
// create ed and add it (and any related components) to mMenu
// ed's value will be set below
ComponentListRow row ;
auto lbl = std : : make_shared < TextComponent > ( mWindow , strToUpper ( iter - > displayName ) , Font : : get ( FONT_SIZE_SMALL ) , 0x777777FF ) ;
row . addElement ( lbl , true ) ; // label
switch ( iter - > type )
{
2017-06-12 16:38:59 +00:00
case MD_BOOL :
{
ed = std : : make_shared < SwitchComponent > ( window ) ;
row . addElement ( ed , false , true ) ;
break ;
}
2014-06-25 16:29:58 +00:00
case MD_RATING :
{
ed = std : : make_shared < RatingComponent > ( window ) ;
const float height = lbl - > getSize ( ) . y ( ) * 0.71f ;
ed - > setSize ( 0 , height ) ;
row . addElement ( ed , false , true ) ;
auto spacer = std : : make_shared < GuiComponent > ( mWindow ) ;
spacer - > setSize ( Renderer : : getScreenWidth ( ) * 0.0025f , 0 ) ;
row . addElement ( spacer , false ) ;
// pass input to the actual RatingComponent instead of the spacer
row . input_handler = std : : bind ( & GuiComponent : : input , ed . get ( ) , std : : placeholders : : _1 , std : : placeholders : : _2 ) ;
break ;
}
case MD_DATE :
{
ed = std : : make_shared < DateTimeComponent > ( window ) ;
row . addElement ( ed , false ) ;
auto spacer = std : : make_shared < GuiComponent > ( mWindow ) ;
spacer - > setSize ( Renderer : : getScreenWidth ( ) * 0.0025f , 0 ) ;
row . addElement ( spacer , false ) ;
// pass input to the actual DateTimeComponent instead of the spacer
row . input_handler = std : : bind ( & GuiComponent : : input , ed . get ( ) , std : : placeholders : : _1 , std : : placeholders : : _2 ) ;
break ;
}
case MD_TIME :
{
ed = std : : make_shared < DateTimeComponent > ( window , DateTimeComponent : : DISP_RELATIVE_TO_NOW ) ;
row . addElement ( ed , false ) ;
break ;
}
case MD_MULTILINE_STRING :
default :
{
// MD_STRING
ed = std : : make_shared < TextComponent > ( window , " " , Font : : get ( FONT_SIZE_SMALL , FONT_PATH_LIGHT ) , 0x777777FF , ALIGN_RIGHT ) ;
row . addElement ( ed , true ) ;
2017-05-18 10:16:57 +00:00
2014-06-25 16:29:58 +00:00
auto spacer = std : : make_shared < GuiComponent > ( mWindow ) ;
spacer - > setSize ( Renderer : : getScreenWidth ( ) * 0.005f , 0 ) ;
row . addElement ( spacer , false ) ;
auto bracket = std : : make_shared < ImageComponent > ( mWindow ) ;
bracket - > setImage ( " :/arrow.svg " ) ;
bracket - > setResize ( Eigen : : Vector2f ( 0 , lbl - > getFont ( ) - > getLetterHeight ( ) ) ) ;
row . addElement ( bracket , false ) ;
bool multiLine = iter - > type = = MD_MULTILINE_STRING ;
const std : : string title = iter - > displayPrompt ;
auto updateVal = [ ed ] ( const std : : string & newVal ) { ed - > setValue ( newVal ) ; } ; // ok callback (apply new value to ed)
row . makeAcceptInputHandler ( [ this , title , ed , updateVal , multiLine ] {
mWindow - > pushGui ( new GuiTextEditPopup ( mWindow , title , ed - > getValue ( ) , updateVal , multiLine ) ) ;
} ) ;
break ;
}
}
assert ( ed ) ;
mList - > addRow ( row ) ;
ed - > setValue ( mMetaData - > get ( iter - > key ) ) ;
mEditors . push_back ( ed ) ;
}
std : : vector < std : : shared_ptr < ButtonComponent > > buttons ;
if ( ! scraperParams . system - > hasPlatformId ( PlatformIds : : PLATFORM_IGNORE ) )
buttons . push_back ( std : : make_shared < ButtonComponent > ( mWindow , " SCRAPE " , " scrape " , std : : bind ( & GuiMetaDataEd : : fetch , this ) ) ) ;
buttons . push_back ( std : : make_shared < ButtonComponent > ( mWindow , " SAVE " , " save " , [ & ] { save ( ) ; delete this ; } ) ) ;
buttons . push_back ( std : : make_shared < ButtonComponent > ( mWindow , " CANCEL " , " cancel " , [ & ] { delete this ; } ) ) ;
if ( mDeleteFunc )
{
auto deleteFileAndSelf = [ & ] { mDeleteFunc ( ) ; delete this ; } ;
auto deleteBtnFunc = [ this , deleteFileAndSelf ] { mWindow - > pushGui ( new GuiMsgBox ( mWindow , " THIS WILL DELETE A FILE! \n ARE YOU SURE? " , " YES " , deleteFileAndSelf , " NO " , nullptr ) ) ; } ;
buttons . push_back ( std : : make_shared < ButtonComponent > ( mWindow , " DELETE " , " delete " , deleteBtnFunc ) ) ;
}
mButtons = makeButtonGrid ( mWindow , buttons ) ;
mGrid . setEntry ( mButtons , Vector2i ( 0 , 2 ) , true , false ) ;
2017-10-18 14:19:32 +00:00
// resize + center
float width = ( float ) std : : min ( Renderer : : getScreenHeight ( ) , ( unsigned int ) ( Renderer : : getScreenWidth ( ) * 0.90f ) ) ;
2017-08-30 00:47:04 +00:00
setSize ( width , Renderer : : getScreenHeight ( ) * 0.82f ) ;
2014-06-25 16:29:58 +00:00
setPosition ( ( Renderer : : getScreenWidth ( ) - mSize . x ( ) ) / 2 , ( Renderer : : getScreenHeight ( ) - mSize . y ( ) ) / 2 ) ;
}
void GuiMetaDataEd : : onSizeChanged ( )
{
mBackground . fitTo ( mSize , Vector3f : : Zero ( ) , Vector2f ( - 32 , - 32 ) ) ;
mGrid . setSize ( mSize ) ;
const float titleHeight = mTitle - > getFont ( ) - > getLetterHeight ( ) ;
const float subtitleHeight = mSubtitle - > getFont ( ) - > getLetterHeight ( ) ;
const float titleSubtitleSpacing = mSize . y ( ) * 0.03f ;
mGrid . setRowHeightPerc ( 0 , ( titleHeight + titleSubtitleSpacing + subtitleHeight + TITLE_VERT_PADDING ) / mSize . y ( ) ) ;
mGrid . setRowHeightPerc ( 2 , mButtons - > getSize ( ) . y ( ) / mSize . y ( ) ) ;
mHeaderGrid - > setRowHeightPerc ( 1 , titleHeight / mHeaderGrid - > getSize ( ) . y ( ) ) ;
mHeaderGrid - > setRowHeightPerc ( 2 , titleSubtitleSpacing / mHeaderGrid - > getSize ( ) . y ( ) ) ;
mHeaderGrid - > setRowHeightPerc ( 3 , subtitleHeight / mHeaderGrid - > getSize ( ) . y ( ) ) ;
}
void GuiMetaDataEd : : save ( )
{
2017-03-18 17:54:39 +00:00
// remove game from index
mScraperParams . system - > getIndex ( ) - > removeFromIndex ( mScraperParams . game ) ;
2014-06-25 16:29:58 +00:00
for ( unsigned int i = 0 ; i < mEditors . size ( ) ; i + + )
{
if ( mMetaDataDecl . at ( i ) . isStatistic )
continue ;
mMetaData - > set ( mMetaDataDecl . at ( i ) . key , mEditors . at ( i ) - > getValue ( ) ) ;
}
2017-03-18 17:54:39 +00:00
// enter game in index
mScraperParams . system - > getIndex ( ) - > addToIndex ( mScraperParams . game ) ;
2014-06-25 16:29:58 +00:00
if ( mSavedCallback )
mSavedCallback ( ) ;
2017-06-12 16:38:59 +00:00
// update respective Collection Entries
2017-07-18 09:45:50 +00:00
CollectionSystemManager : : get ( ) - > refreshCollectionSystems ( mScraperParams . game ) ;
2014-06-25 16:29:58 +00:00
}
void GuiMetaDataEd : : fetch ( )
{
GuiGameScraper * scr = new GuiGameScraper ( mWindow , mScraperParams , std : : bind ( & GuiMetaDataEd : : fetchDone , this , std : : placeholders : : _1 ) ) ;
mWindow - > pushGui ( scr ) ;
}
void GuiMetaDataEd : : fetchDone ( const ScraperSearchResult & result )
{
for ( unsigned int i = 0 ; i < mEditors . size ( ) ; i + + )
{
if ( mMetaDataDecl . at ( i ) . isStatistic )
continue ;
const std : : string & key = mMetaDataDecl . at ( i ) . key ;
mEditors . at ( i ) - > setValue ( result . mdl . get ( key ) ) ;
}
}
void GuiMetaDataEd : : close ( bool closeAllWindows )
{
// find out if the user made any changes
bool dirty = false ;
for ( unsigned int i = 0 ; i < mEditors . size ( ) ; i + + )
{
const std : : string & key = mMetaDataDecl . at ( i ) . key ;
if ( mMetaData - > get ( key ) ! = mEditors . at ( i ) - > getValue ( ) )
{
dirty = true ;
break ;
}
}
std : : function < void ( ) > closeFunc ;
if ( ! closeAllWindows )
{
closeFunc = [ this ] { delete this ; } ;
} else {
Window * window = mWindow ;
closeFunc = [ window , this ] {
while ( window - > peekGui ( ) ! = ViewController : : get ( ) )
delete window - > peekGui ( ) ;
} ;
}
if ( dirty )
{
// changes were made, ask if the user wants to save them
2017-05-18 10:16:57 +00:00
mWindow - > pushGui ( new GuiMsgBox ( mWindow ,
2014-06-25 16:29:58 +00:00
" SAVE CHANGES? " ,
" YES " , [ this , closeFunc ] { save ( ) ; closeFunc ( ) ; } ,
" NO " , closeFunc
) ) ;
} else {
closeFunc ( ) ;
}
}
bool GuiMetaDataEd : : input ( InputConfig * config , Input input )
{
if ( GuiComponent : : input ( config , input ) )
return true ;
const bool isStart = config - > isMappedTo ( " start " , input ) ;
if ( input . value ! = 0 & & ( config - > isMappedTo ( " b " , input ) | | isStart ) )
{
close ( isStart ) ;
return true ;
}
return false ;
}
std : : vector < HelpPrompt > GuiMetaDataEd : : getHelpPrompts ( )
{
std : : vector < HelpPrompt > prompts = mGrid . getHelpPrompts ( ) ;
prompts . push_back ( HelpPrompt ( " b " , " back " ) ) ;
prompts . push_back ( HelpPrompt ( " start " , " close " ) ) ;
return prompts ;
}