diff --git a/TODO.md b/TODO.md index a1f24e283..e14dc9194 100644 --- a/TODO.md +++ b/TODO.md @@ -1,18 +1,30 @@ -# TODO - Short and mid term plans. +# TODO + +## Graphics Module + +* Implement shared pointers for resource management in eepp ## UI Module +* Implement a better DropDownList (model/view approach) + * Implement a Rich Text View. -* Implement a Flex layout. - -* Implement support for very simple state-changes from the XML file (ex: onclick="toggleclass(x)"). - * Implement TableView and TreeView properties. +* Add automatic font-fallback for lang scripts + * Implement support for setting and creating a model from the XML. +* Implement support for very simple state-changes from the XML file (ex: onclick="toggleclass(x)"). + +* Implement a Markdown View + +* Implement smooth-scrolling for macOS + +* Implement UITabWidgetSplitter + ### CSS * Add support for [calc](https://developer.mozilla.org/en-US/docs/Web/CSS/calc). diff --git a/include/eepp/ui/uidropdownlist.hpp b/include/eepp/ui/uidropdownlist.hpp index 3f769e6c1..66f1a619e 100644 --- a/include/eepp/ui/uidropdownlist.hpp +++ b/include/eepp/ui/uidropdownlist.hpp @@ -20,8 +20,7 @@ class EE_API UIDropDownList : public UITextInput { static std::string menuWidthModeToString( MenuWidthMode rule ); - class StyleConfig { - public: + struct StyleConfig { Uint32 MaxNumVisibleItems = 10; bool PopUpToRoot = false; MenuWidthMode menuWidthRule{ MenuWidthMode::DropDown }; diff --git a/src/tools/ecode/plugins/aiassistant/llmprovidermodel.cpp b/src/tools/ecode/plugins/aiassistant/llmprovidermodel.cpp new file mode 100644 index 000000000..42bec9401 --- /dev/null +++ b/src/tools/ecode/plugins/aiassistant/llmprovidermodel.cpp @@ -0,0 +1,131 @@ +#include "llmprovidermodel.hpp" +#include + +namespace ecode { + +std::shared_ptr LLMProviderModel::create( const LLMProviders& model ) { + return std::make_shared( model ); +} + +LLMProviderModel::LLMProviderModel( const LLMProviders& model ) : mProviders( model ) { + resetFilter(); +} + +LLMProviderModel::~LLMProviderModel() {} + +size_t LLMProviderModel::rowCount( const ModelIndex& parent ) const { + if ( !parent.isValid() ) + return mItems.size(); + + if ( parent.internalId() == -1 ) + return mItems[parent.row()].models.size(); + + return 0; +} + +size_t LLMProviderModel::columnCount( const ModelIndex& ) const { + return 1; +} + +ModelIndex LLMProviderModel::index( int row, int column, const ModelIndex& parent ) const { + if ( row < 0 || column < 0 ) + return {}; + + if ( !parent.isValid() ) { + if ( row < (int)mItems.size() ) + return createIndex( row, column, (void*)mItems[row].provider, -1 ); + return {}; + } + + if ( parent.internalId() == -1 ) { + // Parent is a provider + if ( row < (int)mItems[parent.row()].models.size() ) + return createIndex( row, column, (void*)mItems[parent.row()].models[row], + parent.row() ); + } + + return {}; +} + +ModelIndex LLMProviderModel::parentIndex( const ModelIndex& index ) const { + if ( !index.isValid() || index.internalId() == -1 ) + return {}; + + // internalId is the row index of the provider + int providerRow = (int)index.internalId(); + if ( providerRow >= 0 && providerRow < (int)mItems.size() ) { + return createIndex( providerRow, 0, (void*)mItems[providerRow].provider, -1 ); + } + + return {}; +} + +Variant LLMProviderModel::data( const ModelIndex& index, ModelRole role ) const { + if ( !index.isValid() ) + return {}; + + if ( role == ModelRole::Display ) { + if ( index.internalId() == -1 ) { + const LLMProvider* provider = static_cast( index.internalData() ); + return Variant( provider->displayName.value_or( provider->name ) ); + } else { + const LLMModel* model = static_cast( index.internalData() ); + return Variant( model->displayName.value_or( model->name ) ); + } + } else if ( role == ModelRole::Custom ) { + return Variant( index.internalData() ); + } + + return {}; +} + +void LLMProviderModel::filter( const std::string& filterText ) { + if ( filterText.empty() ) { + resetFilter(); + return; + } + + mItems.clear(); + std::string lowerFilter = String::toLower( filterText ); + + for ( const auto& [key, provider] : mProviders ) { + std::string pName = provider.displayName.value_or( provider.name ); + bool providerMatches = String::icontains( pName, lowerFilter ); + + ProviderData data; + data.provider = &provider; + + if ( providerMatches ) { + for ( const auto& model : provider.models ) { + data.models.push_back( &model ); + } + } else { + for ( const auto& model : provider.models ) { + std::string mName = model.displayName.value_or( model.name ); + if ( String::icontains( mName, lowerFilter ) ) { + data.models.push_back( &model ); + } + } + } + + if ( providerMatches || !data.models.empty() ) { + mItems.emplace_back( std::move( data ) ); + } + } + invalidate( Model::UpdateFlag::InvalidateAllIndexes ); +} + +void LLMProviderModel::resetFilter() { + mItems.clear(); + for ( const auto& [key, provider] : mProviders ) { + ProviderData data; + data.provider = &provider; + for ( const auto& model : provider.models ) { + data.models.push_back( &model ); + } + mItems.emplace_back( std::move( data ) ); + } + invalidate( Model::UpdateFlag::InvalidateAllIndexes ); +} + +} // namespace ecode diff --git a/src/tools/ecode/plugins/aiassistant/llmprovidermodel.hpp b/src/tools/ecode/plugins/aiassistant/llmprovidermodel.hpp new file mode 100644 index 000000000..9172d3ac1 --- /dev/null +++ b/src/tools/ecode/plugins/aiassistant/llmprovidermodel.hpp @@ -0,0 +1,48 @@ +#ifndef ECODE_AIASSISTANT_LLMPROVIDERMODEL_HPP +#define ECODE_AIASSISTANT_LLMPROVIDERMODEL_HPP + +#include "protocol.hpp" +#include + +using namespace EE; +using namespace EE::UI::Models; + +namespace ecode { + +class LLMProviderModel : public Model { + public: + static std::shared_ptr create( const LLMProviders& model ); + + explicit LLMProviderModel( const LLMProviders& model ); + + virtual ~LLMProviderModel(); + + virtual size_t rowCount( const ModelIndex& parent = ModelIndex() ) const override; + + virtual size_t columnCount( const ModelIndex& parent = ModelIndex() ) const override; + + virtual ModelIndex index( int row, int column, + const ModelIndex& parent = ModelIndex() ) const override; + + virtual ModelIndex parentIndex( const ModelIndex& index ) const override; + + virtual Variant data( const ModelIndex& index, + ModelRole role = ModelRole::Display ) const override; + + void filter( const std::string& filter ); + + protected: + struct ProviderData { + const LLMProvider* provider; + std::vector models; + }; + + LLMProviders mProviders; + std::vector mItems; + + void resetFilter(); +}; + +} // namespace ecode + +#endif // ECODE_AIASSISTANT_LLMPROVIDERMODEL_HPP