#19
by usao » 1年前
雰囲気書いてみたっす.
(↓のmain() の記述でしか動作確認してないけど)
ボタンの隣接関係の登録時には「ID」という値で指定.
↓
コンテナ自体は単に自身が持つ vector の index 値で全ての情報を保持.
コード:
//ボタン.※ここでは単にTextを持つだけ.
class Button
{
private:
std::string m_Text;
public:
Button( const std::string &Text ) : m_Text{Text} {}
const std::string &Text() const { return m_Text; }
};
//「コンテナ」
class ButtonContainer
{
private:
//ボタンと,各ボタンからの4方向のフォーカス移動先.(移動先の値は m_Data のindex)
std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > m_Data;
//現在フォーカスがあるボタンを示す m_Data のindex.該当が無い場合は負の値とする.
int m_iCurrFocusButton;
private:
//private ctor : Builder からのみ構築できる.
ButtonContainer( std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > &&Data, int iCurrFocus )
: m_Data( std::move(Data) ), m_iCurrFocusButton(iCurrFocus)
{}
ButtonContainer( const ButtonContainer & ) = delete;
ButtonContainer &operator=( const ButtonContainer & ) = delete;
public:
//※これは単に保持データの中身を確認するテスト
void TestShow() const
{
for( size_t i=0; i<m_Data.size(); ++i )
{
std::cout << "[" << i << "]:" << m_Data[i].first->Text() << " ";
for( int idx : m_Data[i].second ){ std::cout << "," << idx; }
std::cout << std::endl;
}
std::cout << "Index of Curr Focus Button : " << m_iCurrFocusButton << std::endl;
}
//-------------
public: //ButtonContainer生成器
class Builder
{
private:
std::map< int, std::pair< std::shared_ptr<Button>, std::array<int,4> > > m_Data;
public:
//ctor : 引数は Add() と同じ
Builder( std::shared_ptr<Button> spButton, int ID, const std::array<int,4> &NeighborIDs )
{ Add( spButton, ID, NeighborIDs ); }
public:
//ボタンと,そのボタンを示すID値,フォーカス移動先の4方向のボタンのID値を指定して情報を登録.
//(ある方向にフォーカス移動先が無い場合は,存在しないID値を指定する)
Builder &Add( std::shared_ptr<Button> spButton, int ID, const std::array<int,4> &NeighborIDs )
{
m_Data[ID] = std::pair< std::shared_ptr<Button>, std::array<int,4> >( spButton, NeighborIDs );
return *this;
}
//登録されている情報から ButtonContainer を生成する.
//引数は初期にフォーカスを持つボタンのID.
//(初期フォーカス無し状態とする場合には登録されていないID値を指定する)
std::unique_ptr< ButtonContainer > Build( int InitFocusButtonID ) const
{
std::vector< int > IDs;
IDs.reserve( m_Data.size() );
for( const auto &D : m_Data ){ IDs.push_back(D.first); }
std::sort( IDs.begin(), IDs.end() ); //←別に要らんかも
std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > Result;
Result.reserve( IDs.size() );
for( int ID : IDs )
{
const auto d = m_Data.at(ID);
std::array<int,4> NeighborIndex;
for( int i=0; i<4; ++i )
{
auto iFound = std::find( IDs.begin(), IDs.end(), d.second[i] );
NeighborIndex[i] = (iFound!=IDs.end() ? (int)std::distance( IDs.begin(), iFound ) : -1 );
}
Result.emplace_back( d.first, std::move(NeighborIndex) );
}
int InitFocusIndex = -1;
{
auto iFound = std::find( IDs.begin(), IDs.end(), InitFocusButtonID );
if( iFound != IDs.end() ){ InitFocusIndex = (int)std::distance( IDs.begin(), iFound ); }
}
return std::unique_ptr<ButtonContainer>( new ButtonContainer( std::move(Result), InitFocusIndex ) );
}
};
};
//main
int main( /*int argc, const char *argv[]*/ )
{
//やってみる
std::unique_ptr<ButtonContainer> spContainer =
ButtonContainer::Builder( std::make_shared<Button>( "B1" ), 1, { 99,0,2,0 } )
.Add( std::make_shared<Button>( "B2" ), 2, { 0,0,0,1 } )
.Add( std::make_shared<Button>( "B99" ), 99, { 0,1,0,0 } )
.Build( 99 );
spContainer->TestShow();
return 0;
}
雰囲気書いてみたっす.
(↓のmain() の記述でしか動作確認してないけど)
ボタンの隣接関係の登録時には「ID」という値で指定.
↓
コンテナ自体は単に自身が持つ vector の index 値で全ての情報を保持.
[code]
//ボタン.※ここでは単にTextを持つだけ.
class Button
{
private:
std::string m_Text;
public:
Button( const std::string &Text ) : m_Text{Text} {}
const std::string &Text() const { return m_Text; }
};
//「コンテナ」
class ButtonContainer
{
private:
//ボタンと,各ボタンからの4方向のフォーカス移動先.(移動先の値は m_Data のindex)
std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > m_Data;
//現在フォーカスがあるボタンを示す m_Data のindex.該当が無い場合は負の値とする.
int m_iCurrFocusButton;
private:
//private ctor : Builder からのみ構築できる.
ButtonContainer( std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > &&Data, int iCurrFocus )
: m_Data( std::move(Data) ), m_iCurrFocusButton(iCurrFocus)
{}
ButtonContainer( const ButtonContainer & ) = delete;
ButtonContainer &operator=( const ButtonContainer & ) = delete;
public:
//※これは単に保持データの中身を確認するテスト
void TestShow() const
{
for( size_t i=0; i<m_Data.size(); ++i )
{
std::cout << "[" << i << "]:" << m_Data[i].first->Text() << " ";
for( int idx : m_Data[i].second ){ std::cout << "," << idx; }
std::cout << std::endl;
}
std::cout << "Index of Curr Focus Button : " << m_iCurrFocusButton << std::endl;
}
//-------------
public: //ButtonContainer生成器
class Builder
{
private:
std::map< int, std::pair< std::shared_ptr<Button>, std::array<int,4> > > m_Data;
public:
//ctor : 引数は Add() と同じ
Builder( std::shared_ptr<Button> spButton, int ID, const std::array<int,4> &NeighborIDs )
{ Add( spButton, ID, NeighborIDs ); }
public:
//ボタンと,そのボタンを示すID値,フォーカス移動先の4方向のボタンのID値を指定して情報を登録.
//(ある方向にフォーカス移動先が無い場合は,存在しないID値を指定する)
Builder &Add( std::shared_ptr<Button> spButton, int ID, const std::array<int,4> &NeighborIDs )
{
m_Data[ID] = std::pair< std::shared_ptr<Button>, std::array<int,4> >( spButton, NeighborIDs );
return *this;
}
//登録されている情報から ButtonContainer を生成する.
//引数は初期にフォーカスを持つボタンのID.
//(初期フォーカス無し状態とする場合には登録されていないID値を指定する)
std::unique_ptr< ButtonContainer > Build( int InitFocusButtonID ) const
{
std::vector< int > IDs;
IDs.reserve( m_Data.size() );
for( const auto &D : m_Data ){ IDs.push_back(D.first); }
std::sort( IDs.begin(), IDs.end() ); //←別に要らんかも
std::vector< std::pair< std::shared_ptr<Button>, std::array<int,4> > > Result;
Result.reserve( IDs.size() );
for( int ID : IDs )
{
const auto d = m_Data.at(ID);
std::array<int,4> NeighborIndex;
for( int i=0; i<4; ++i )
{
auto iFound = std::find( IDs.begin(), IDs.end(), d.second[i] );
NeighborIndex[i] = (iFound!=IDs.end() ? (int)std::distance( IDs.begin(), iFound ) : -1 );
}
Result.emplace_back( d.first, std::move(NeighborIndex) );
}
int InitFocusIndex = -1;
{
auto iFound = std::find( IDs.begin(), IDs.end(), InitFocusButtonID );
if( iFound != IDs.end() ){ InitFocusIndex = (int)std::distance( IDs.begin(), iFound ); }
}
return std::unique_ptr<ButtonContainer>( new ButtonContainer( std::move(Result), InitFocusIndex ) );
}
};
};
//main
int main( /*int argc, const char *argv[]*/ )
{
//やってみる
std::unique_ptr<ButtonContainer> spContainer =
ButtonContainer::Builder( std::make_shared<Button>( "B1" ), 1, { 99,0,2,0 } )
.Add( std::make_shared<Button>( "B2" ), 2, { 0,0,0,1 } )
.Add( std::make_shared<Button>( "B99" ), 99, { 0,1,0,0 } )
.Build( 99 );
spContainer->TestShow();
return 0;
}
[/code]