mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
eepp:
UIAbstractTableView added support for selection type (row or cell). ModelEditingDelegate, UIDataBind, UISpinBox, UITableHeaderColumn, ItemListModel fixes. ecode: UIBuildSettings almost done.
This commit is contained in:
@@ -904,6 +904,26 @@ treeview::row:selected {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
tableview.selection_type_cell tableview::row:hover,
|
||||
treeview.selection_type_cell treeview::row:hover {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tableview.selection_type_cell tableview::row:selected,
|
||||
treeview.selection_type_cell treeview::row:selected {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
tableview.selection_type_cell tableview::cell:hover,
|
||||
treeview.selection_type_cell treeview::cell:hover {
|
||||
background-color: var(--tab-hover);
|
||||
}
|
||||
|
||||
tableview.selection_type_cell tableview::cell:selected,
|
||||
treeview.selection_type_cell tableview::cell:selected {
|
||||
background-color: var(--primary);
|
||||
}
|
||||
|
||||
tableview::cell,
|
||||
treeview::cell {
|
||||
padding-left: 6dp;
|
||||
|
||||
@@ -49,6 +49,12 @@ class EE_API UIAbstractView : public UIScrollableWidget {
|
||||
AnyKeyPressed = 1 << 2,
|
||||
};
|
||||
|
||||
enum SelectionType { Row, Cell };
|
||||
|
||||
bool isCellSelection() const;
|
||||
|
||||
bool isRowSelection() const;
|
||||
|
||||
Uint32 getType() const;
|
||||
|
||||
bool isType( const Uint32& type ) const;
|
||||
@@ -98,6 +104,9 @@ class EE_API UIAbstractView : public UIScrollableWidget {
|
||||
|
||||
std::function<ModelEditingDelegate*( const ModelIndex& )> onCreateEditingDelegate;
|
||||
|
||||
SelectionType getSelectionType() const;
|
||||
void setSelectionType( SelectionType selectionType );
|
||||
|
||||
protected:
|
||||
friend class EE::UI::Models::Model;
|
||||
|
||||
@@ -124,6 +133,7 @@ class EE_API UIAbstractView : public UIScrollableWidget {
|
||||
|
||||
Uint32 mEditTriggers{ EditTrigger::None };
|
||||
KeyBindings::Shortcut mEditShortcut{ KEY_F2 };
|
||||
SelectionType mSelectionType{ SelectionType::Row };
|
||||
|
||||
virtual void editingWidgetDidChange( const ModelIndex& ) {}
|
||||
};
|
||||
|
||||
@@ -23,8 +23,7 @@ template <typename T> class ItemListModel final : public Model {
|
||||
|
||||
virtual std::string columnName( const size_t& ) const { return "Data"; }
|
||||
|
||||
virtual ModelIndex index( int row, int column,
|
||||
const ModelIndex& parent = ModelIndex() ) const override {
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
@@ -66,8 +65,7 @@ template <typename K, typename V> class ItemPairListModel final : public Model {
|
||||
mColumnNames[index] = name;
|
||||
}
|
||||
|
||||
virtual ModelIndex index( int row, int column,
|
||||
const ModelIndex& parent = ModelIndex() ) const override {
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
@@ -125,8 +123,7 @@ template <typename T> class ItemListOwnerModel final : public Model {
|
||||
|
||||
virtual std::string columnName( const size_t& ) const { return "Data"; }
|
||||
|
||||
virtual ModelIndex index( int row, int column,
|
||||
const ModelIndex& parent = ModelIndex() ) const override {
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
@@ -180,8 +177,7 @@ template <typename K, typename V> class ItemPairListOwnerModel final : public Mo
|
||||
mColumnNames[index] = name;
|
||||
}
|
||||
|
||||
virtual ModelIndex index( int row, int column,
|
||||
const ModelIndex& parent = ModelIndex() ) const override {
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
@@ -252,8 +248,7 @@ template <typename V> class ItemVectorListOwnerModel final : public Model {
|
||||
mColumnNames[index] = name;
|
||||
}
|
||||
|
||||
virtual ModelIndex index( int row, int column,
|
||||
const ModelIndex& parent = ModelIndex() ) const override {
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
|
||||
@@ -31,12 +31,16 @@ class EE_API ModelEditingDelegate {
|
||||
std::function<void()> onCommit;
|
||||
std::function<void()> onRollback;
|
||||
std::function<void()> onChange;
|
||||
std::function<void()> onWillBeginEditing;
|
||||
|
||||
virtual Variant getValue() const = 0;
|
||||
|
||||
virtual void setValue( const Variant& ) = 0;
|
||||
|
||||
virtual void willBeginEditing() {}
|
||||
virtual void willBeginEditing() {
|
||||
if ( onWillBeginEditing )
|
||||
onWillBeginEditing();
|
||||
}
|
||||
|
||||
ModelIndex const& index() const { return mIndex; }
|
||||
|
||||
@@ -95,6 +99,8 @@ class EE_API StringModelEditingDelegate : public ModelEditingDelegate {
|
||||
void willBeginEditing() override {
|
||||
if ( mSelectionBehavior == SelectionBehavior::SelectAll )
|
||||
getWidget()->asType<UITextInput>()->getDocument().selectAll();
|
||||
|
||||
ModelEditingDelegate::willBeginEditing();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -250,10 +250,12 @@ class UIDataBindString {
|
||||
class UIDataBindHolder {
|
||||
public:
|
||||
using UIDataBindVariant =
|
||||
std::variant<UIDataBindString::Ptr, UIDataBindBool::Ptr, UIDataBind<Uint32>,
|
||||
UIDataBind<Int32>, UIDataBind<Uint64>, UIDataBind<Int64>, UIDataBind<Uint8>,
|
||||
UIDataBind<Int8>, UIDataBind<Uint16>, UIDataBind<Int16>, UIDataBind<float>,
|
||||
UIDataBind<double>>;
|
||||
std::variant<UIDataBindString::Ptr, UIDataBindBool::Ptr,
|
||||
std::unique_ptr<UIDataBind<Uint32>>, std::unique_ptr<UIDataBind<Int32>>,
|
||||
std::unique_ptr<UIDataBind<Uint64>>, std::unique_ptr<UIDataBind<Int64>>,
|
||||
std::unique_ptr<UIDataBind<Uint8>>, std::unique_ptr<UIDataBind<Int8>>,
|
||||
std::unique_ptr<UIDataBind<Uint16>>, std::unique_ptr<UIDataBind<Int16>>,
|
||||
std::unique_ptr<UIDataBind<float>>, std::unique_ptr<UIDataBind<double>>>;
|
||||
|
||||
UIDataBindHolder& hold( UIDataBindVariant&& ptr ) {
|
||||
mHolder.emplace_back( std::move( ptr ) );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 10.0.1, 2023-05-28T03:09:27. -->
|
||||
<!-- Written by QtCreator 10.0.1, 2023-06-06T01:22:08. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
@@ -110,7 +110,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{388e5431-b31b-42b3-b9ad-9002d279d75d}</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">10</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">15</value>
|
||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">19</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">../../make/linux</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
@@ -1107,7 +1107,7 @@
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">eepp-UIEditor-debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"> -u --xml=/home/downloads/build_settings.xml</value>
|
||||
<value type="QString" key="RunConfiguration.Arguments"> -u</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
|
||||
@@ -262,7 +262,7 @@ void UIAbstractTableView::updateHeaderSize() {
|
||||
size_t count = getModel()->columnCount();
|
||||
Float totalWidth = 0;
|
||||
for ( size_t i = 0; i < count; i++ ) {
|
||||
ColumnData& col = columnData( i );
|
||||
const ColumnData& col = columnData( i );
|
||||
totalWidth += col.width;
|
||||
}
|
||||
mHeader->setPixelsSize( totalWidth, getHeaderHeight() );
|
||||
@@ -419,7 +419,7 @@ UITableRow* UIAbstractTableView::createRow() {
|
||||
rowWidget->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||
rowWidget->reloadStyle( true, true, true );
|
||||
rowWidget->addEventListener( Event::MouseDown, [&]( const Event* event ) {
|
||||
if ( !( event->asMouseEvent()->getFlags() & EE_BUTTON_LMASK ) )
|
||||
if ( !( event->asMouseEvent()->getFlags() & EE_BUTTON_LMASK ) || !isRowSelection() )
|
||||
return;
|
||||
getSelection().set( event->getNode()->asType<UITableRow>()->getCurIndex() );
|
||||
} );
|
||||
@@ -440,10 +440,12 @@ UITableRow* UIAbstractTableView::updateRow( const int& rowIndex, const ModelInde
|
||||
rowWidget->setCurIndex( index );
|
||||
rowWidget->setPixelsSize( getContentSize().getWidth(), getRowHeight() );
|
||||
rowWidget->setPixelsPosition( { -mScrollOffset.x, yOffset - mScrollOffset.y } );
|
||||
if ( getSelection().contains( index ) ) {
|
||||
rowWidget->pushState( UIState::StateSelected );
|
||||
} else {
|
||||
rowWidget->popState( UIState::StateSelected );
|
||||
if ( isRowSelection() ) {
|
||||
if ( getSelection().contains( index ) ) {
|
||||
rowWidget->pushState( UIState::StateSelected );
|
||||
} else {
|
||||
rowWidget->popState( UIState::StateSelected );
|
||||
}
|
||||
}
|
||||
return rowWidget;
|
||||
}
|
||||
@@ -474,6 +476,9 @@ void UIAbstractTableView::bindNavigationClick( UIWidget* widget ) {
|
||||
onOpenMenuModelIndex( idx, event );
|
||||
} else if ( ( mouseEvent->getFlags() & EE_BUTTON_LMASK ) && mSingleClickNavigation ) {
|
||||
onOpenModelIndex( idx, event );
|
||||
} else if ( isCellSelection() && ( mouseEvent->getFlags() & EE_BUTTON_LMASK ) ) {
|
||||
auto cellIdx = mouseEvent->getNode()->asType<UITableCell>()->getCurIndex();
|
||||
getSelection().set( cellIdx );
|
||||
}
|
||||
} ) );
|
||||
}
|
||||
@@ -545,6 +550,14 @@ UIWidget* UIAbstractTableView::updateCell( const int& rowIndex, const ModelIndex
|
||||
cell->updateCell( getModel() );
|
||||
}
|
||||
|
||||
if ( isCellSelection() ) {
|
||||
if ( getSelection().contains( index ) ) {
|
||||
widget->pushState( UIState::StateSelected );
|
||||
} else {
|
||||
widget->popState( UIState::StateSelected );
|
||||
}
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
@@ -672,14 +685,14 @@ Uint32 UIAbstractTableView::onTextInput( const TextInputEvent& event ) {
|
||||
String::startsWith( String::toLower( var.toString() ), mSearchText ) ) {
|
||||
setSelection( model->index( next.row(), 0, next.parent() ) );
|
||||
} else {
|
||||
ModelIndex index = findRowWithText( mSearchText );
|
||||
if ( index.isValid() )
|
||||
setSelection( index );
|
||||
ModelIndex fIndex = findRowWithText( mSearchText );
|
||||
if ( fIndex.isValid() )
|
||||
setSelection( fIndex );
|
||||
}
|
||||
} else {
|
||||
ModelIndex index = findRowWithText( mSearchText );
|
||||
if ( index.isValid() )
|
||||
setSelection( index );
|
||||
ModelIndex fIndex = findRowWithText( mSearchText );
|
||||
if ( fIndex.isValid() )
|
||||
setSelection( fIndex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,20 @@ UIAbstractView::~UIAbstractView() {
|
||||
eeSAFE_DELETE( mEditingDelegate );
|
||||
}
|
||||
|
||||
UIAbstractView::SelectionType UIAbstractView::getSelectionType() const {
|
||||
return mSelectionType;
|
||||
}
|
||||
|
||||
void UIAbstractView::setSelectionType( SelectionType selectionType ) {
|
||||
mSelectionType = selectionType;
|
||||
|
||||
if ( selectionType == UIAbstractView::SelectionType::Cell ) {
|
||||
addClass( "selection_type_cell" );
|
||||
} else {
|
||||
removeClass( "selection_type_cell" );
|
||||
}
|
||||
}
|
||||
|
||||
KeyBindings::Shortcut UIAbstractView::getEditShortcut() const {
|
||||
return mEditShortcut;
|
||||
}
|
||||
@@ -33,6 +47,12 @@ bool UIAbstractView::isEditable() const {
|
||||
|
||||
void UIAbstractView::setEditable( bool editable ) {
|
||||
mEditable = editable;
|
||||
|
||||
if ( editable ) {
|
||||
addClass( "editable_cells" );
|
||||
} else {
|
||||
removeClass( "editable_cells" );
|
||||
}
|
||||
}
|
||||
|
||||
std::function<void( const ModelIndex& )> UIAbstractView::getOnSelection() const {
|
||||
@@ -51,6 +71,14 @@ void UIAbstractView::setOnSelectionChange( const std::function<void()>& onSelect
|
||||
mOnSelectionChange = onSelectionChange;
|
||||
}
|
||||
|
||||
bool UIAbstractView::isCellSelection() const {
|
||||
return mSelectionType == UIAbstractView::SelectionType::Cell;
|
||||
}
|
||||
|
||||
bool UIAbstractView::isRowSelection() const {
|
||||
return mSelectionType == UIAbstractView::SelectionType::Row;
|
||||
}
|
||||
|
||||
Uint32 UIAbstractView::getType() const {
|
||||
return UI_TYPE_ABSTRACTVIEW;
|
||||
}
|
||||
@@ -131,7 +159,6 @@ void UIAbstractView::beginEditing( const ModelIndex& index, UIWidget* editedWidg
|
||||
};
|
||||
mEditingDelegate->onRollback = [this]() { stopEditing(); };
|
||||
mEditingDelegate->onChange = [this, index]() { editingWidgetDidChange( index ); };
|
||||
// mEditWidget->on( Event::OnFocusLoss, [this]( auto ) { mEditingDelegate->onRollback(); } );
|
||||
}
|
||||
|
||||
void UIAbstractView::stopEditing() {
|
||||
|
||||
@@ -906,7 +906,7 @@ void StyleSheetSpecification::registerDefaultShorthandParsers() {
|
||||
// boder-style is not implemented yet
|
||||
if ( pos != -1 )
|
||||
continue;
|
||||
} else if ( Color::isColorString( tok ) ) {
|
||||
} else if ( Color::isColorString( tok ) || String::startsWith( tok, "var(" ) ) {
|
||||
int pos = getIndexEndingWith( propNames, "-color" );
|
||||
if ( pos != -1 ) {
|
||||
const ShorthandDefinition* shorthand = getShorthand( propNames[pos] );
|
||||
|
||||
@@ -17,7 +17,7 @@ UISpinBox::UISpinBox() :
|
||||
mValue( 0 ),
|
||||
mClickStep( 1.f ),
|
||||
mModifyingVal( false ) {
|
||||
mFlags |= UI_SCROLLABLE;
|
||||
mFlags |= UI_SCROLLABLE;
|
||||
mInput = UITextInput::NewWithTag( "spinbox::input" );
|
||||
mInput->setVisible( true );
|
||||
mInput->setEnabled( true );
|
||||
@@ -159,24 +159,23 @@ void UISpinBox::addValue( const double& value ) {
|
||||
}
|
||||
|
||||
UISpinBox* UISpinBox::setValue( const double& val ) {
|
||||
if ( val != mValue ) {
|
||||
if ( val >= mMinValue && val <= mMaxValue ) {
|
||||
double iValN = (double)(Int64)val;
|
||||
double fValN = (double)iValN;
|
||||
double newVal = eeclamp( val, mMinValue, mMaxValue );
|
||||
double iValN = (double)(Int64)newVal;
|
||||
double fValN = (double)iValN;
|
||||
bool valueChanged = mValue != newVal;
|
||||
|
||||
mValue = val;
|
||||
mValue = newVal;
|
||||
|
||||
mModifyingVal = true;
|
||||
if ( fValN == val ) {
|
||||
mInput->setText( String::toString( (Int64)iValN ) );
|
||||
} else {
|
||||
mInput->setText( String::toString( val ) );
|
||||
}
|
||||
mModifyingVal = false;
|
||||
|
||||
onValueChange();
|
||||
}
|
||||
mModifyingVal = true;
|
||||
if ( fValN == newVal ) {
|
||||
mInput->setText( String::toString( (Int64)iValN ) );
|
||||
} else {
|
||||
mInput->setText( String::toString( newVal ) );
|
||||
}
|
||||
mModifyingVal = false;
|
||||
|
||||
if ( valueChanged )
|
||||
onValueChange();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -196,12 +195,8 @@ void UISpinBox::onBufferChange( const Event* ) {
|
||||
mInput->setText( mInput->getText().substr( 0, mInput->getText().size() - 1 ) );
|
||||
} else {
|
||||
bool res = String::fromString<double>( val, mInput->getText() );
|
||||
|
||||
if ( res && val != mValue && val >= mMinValue && val <= mMaxValue ) {
|
||||
mValue = val;
|
||||
|
||||
onValueChange();
|
||||
}
|
||||
if ( res && val != mValue )
|
||||
setValue( val );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +221,7 @@ UISpinBox* UISpinBox::setMinValue( const double& minVal ) {
|
||||
mMinValue = minVal;
|
||||
|
||||
if ( mValue < mMinValue )
|
||||
mValue = mMinValue;
|
||||
setValue( mMinValue );
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -239,7 +234,7 @@ UISpinBox* UISpinBox::setMaxValue( const double& maxVal ) {
|
||||
mMaxValue = maxVal;
|
||||
|
||||
if ( mValue > mMaxValue )
|
||||
mValue = mMaxValue;
|
||||
setValue( mMaxValue );
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ Uint32 UITableHeaderColumn::onMouseDown( const Vector2i& position, const Uint32&
|
||||
!( getEventDispatcher()->getLastPressTrigger() & mDragButton ) &&
|
||||
( flags & mDragButton ) && isDragEnabled() && !isDragging() &&
|
||||
localPos.x >= mSize.getWidth() - mView->getDragBorderDistance() ) {
|
||||
setFocus();
|
||||
startDragging( position.asFloat() );
|
||||
}
|
||||
pushState( UIState::StatePressed );
|
||||
|
||||
@@ -3367,12 +3367,8 @@ TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child
|
||||
row-valign: center;
|
||||
}
|
||||
.settings_panel .inner_box {
|
||||
padding-top: 8dp;
|
||||
visible: false;
|
||||
}
|
||||
.settings_panel .inner_box .build_environment > .subtitle {
|
||||
margin-top: 0dp;
|
||||
}
|
||||
.settings_panel .advanced_options {
|
||||
margin-top: 12dp;
|
||||
border-radius: 4dp;
|
||||
@@ -3422,6 +3418,27 @@ TableView#locate_bar_table > tableview::row:selected > tableview::cell:nth-child
|
||||
.settings_panel > .advanced_options > LinearLayout.inner_box.visible {
|
||||
visible: true;
|
||||
}
|
||||
.settings_panel .buttons_box {
|
||||
margin-left:4dp;
|
||||
layout-gravity: center_horizontal|top;
|
||||
}
|
||||
.settings_panel .buttons_box > * {
|
||||
margin-bottom: 4dp;
|
||||
}
|
||||
.settings_panel TableView {
|
||||
margin-top: 4dp;
|
||||
}
|
||||
.custom_output_parser_cont > * {
|
||||
margin-bottom: 4dp;
|
||||
padding-top: 4dp;
|
||||
}
|
||||
.custom_output_parser_cont > .capture_positions_cont {
|
||||
border: 1dp solid var(--tab-line);
|
||||
padding: 4dp;
|
||||
}
|
||||
.custom_output_parser_cont > .capture_positions_cont > * {
|
||||
padding: 2dp;
|
||||
}
|
||||
</style>
|
||||
<MainLayout id="main_layout" lw="mp" lh="mp">
|
||||
<Splitter id="project_splitter" lw="mp" lh="mp">
|
||||
|
||||
@@ -93,9 +93,21 @@ struct ProjectBuildConfig {
|
||||
bool clearSysEnv{ false };
|
||||
};
|
||||
|
||||
enum class ProjectOutputParserTypes { Error, Warning, Notice };
|
||||
enum class ProjectOutputParserTypes { Error = 0, Warning = 1, Notice = 2 };
|
||||
|
||||
struct ProjectBuildOutputParserConfig {
|
||||
static std::string typeToString( ProjectOutputParserTypes type ) {
|
||||
switch ( type ) {
|
||||
case ProjectOutputParserTypes::Notice:
|
||||
return "notice";
|
||||
case ProjectOutputParserTypes::Warning:
|
||||
return "warning";
|
||||
case ProjectOutputParserTypes::Error:
|
||||
default:
|
||||
return "error";
|
||||
}
|
||||
}
|
||||
|
||||
ProjectOutputParserTypes type;
|
||||
std::string pattern;
|
||||
struct {
|
||||
|
||||
@@ -10,6 +10,196 @@ using namespace EE::UI::Models;
|
||||
|
||||
namespace ecode {
|
||||
|
||||
class OutputParserModel final : public Model {
|
||||
public:
|
||||
static std::shared_ptr<OutputParserModel>
|
||||
create( std::vector<ProjectBuildOutputParserConfig>& data,
|
||||
std::function<String( const std::string&, const String& )> i18n ) {
|
||||
return std::make_shared<OutputParserModel>( data, i18n );
|
||||
}
|
||||
|
||||
explicit OutputParserModel( std::vector<ProjectBuildOutputParserConfig>& data,
|
||||
std::function<String( const std::string&, const String& )> i18n ) :
|
||||
mData( data ), i18n( i18n ) {
|
||||
mColumnNames.push_back( i18n( "type", "Type" ) );
|
||||
mColumnNames.push_back( i18n( "pattern", "Pattern" ) );
|
||||
}
|
||||
|
||||
virtual ~OutputParserModel() {}
|
||||
|
||||
virtual size_t rowCount( const ModelIndex& ) const { return mData.size(); }
|
||||
|
||||
virtual size_t columnCount( const ModelIndex& ) const { return 2; }
|
||||
|
||||
virtual std::string columnName( const size_t& index ) const {
|
||||
eeASSERT( index < 2 );
|
||||
return mColumnNames[index];
|
||||
}
|
||||
|
||||
virtual void setColumnName( const size_t& index, const std::string& name ) {
|
||||
eeASSERT( index < 2 );
|
||||
mColumnNames[index] = name;
|
||||
}
|
||||
|
||||
virtual ModelIndex index( int row, int column, const ModelIndex& parent = ModelIndex() ) const {
|
||||
if ( row >= (int)rowCount( parent ) || column >= (int)columnCount( parent ) )
|
||||
return {};
|
||||
return Model::index( row, column, parent );
|
||||
}
|
||||
|
||||
virtual Variant data( const ModelIndex& index, ModelRole role = ModelRole::Display ) const {
|
||||
if ( role == ModelRole::Display ) {
|
||||
switch ( index.column() ) {
|
||||
case 0: {
|
||||
std::string val =
|
||||
ProjectBuildOutputParserConfig::typeToString( mData[index.row()].type );
|
||||
return Variant( i18n( val, String::capitalize( val ) ) );
|
||||
}
|
||||
case 1:
|
||||
default:
|
||||
return Variant( mData[index.row()].pattern );
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual void update() { onModelUpdate(); }
|
||||
|
||||
private:
|
||||
std::vector<ProjectBuildOutputParserConfig>& mData;
|
||||
std::function<String( const std::string&, const String& )> i18n;
|
||||
std::vector<std::string> mColumnNames;
|
||||
};
|
||||
|
||||
class UICustomOutputParserWindow : public UIWindow {
|
||||
public:
|
||||
static UICustomOutputParserWindow* New( ProjectBuildOutputParserConfig& cfg ) {
|
||||
return eeNew( UICustomOutputParserWindow, ( cfg ) );
|
||||
}
|
||||
|
||||
explicit UICustomOutputParserWindow( ProjectBuildOutputParserConfig& cfg ) :
|
||||
UIWindow( SIMPLE_LAYOUT, { UI_WIN_CLOSE_BUTTON | UI_WIN_USE_DEFAULT_BUTTONS_ACTIONS |
|
||||
UI_WIN_SHARE_ALPHA_WITH_CHILDS | UI_WIN_MODAL } ),
|
||||
mTmpCfg( cfg ),
|
||||
mCfg( cfg ) {
|
||||
static const auto CUSTOM_OUTPUT_PARSER_XML = R"xml(
|
||||
<vbox class="custom_output_parser_cont" lw="400dp" lh="wc">
|
||||
<TextView text="@string(type, Type)" />
|
||||
<DropDownList lw="mp" lh="wc" id="custom_parser_type" selectedIndex="0">
|
||||
<item>@string("error", "Error")</item>
|
||||
<item>@string("warning", "Warning")</item>
|
||||
<item>@string("notice", "Notice")</item>
|
||||
</DropDownList>
|
||||
<TextView text="@string(message_capture_pattern, Message Capture Pattern)" />
|
||||
<TextInput lw="mp" lh="wc" id="custom_parser_pattern" hint="@string(lua_pattern, Lua Pattern)" />
|
||||
<TextView text="@string(capture_positions, Capture Positions)" />
|
||||
<hbox lw="mp" lh="wc" class="capture_positions_cont">
|
||||
<vbox lw="0" lw8="0.25" lh="wc">
|
||||
<TextView lw="mp" lh="wc" text="@string(file_name, File Name)" />
|
||||
<SpinBox id="file_name_pos" lw="mp" lh="wc" min-value="0" max-value="4" value="1" />
|
||||
</vbox>
|
||||
<vbox lw="0" lw8="0.25" lh="wc">
|
||||
<TextView lw="mp" lh="wc" text="@string(line_number, Line Number)" />
|
||||
<SpinBox id="line_number_pos" lw="mp" lh="wc" min-value="0" max-value="4" value="2" />
|
||||
</vbox>
|
||||
<vbox lw="0" lw8="0.25" lh="wc">
|
||||
<TextView lw="mp" lh="wc" text="@string(column_position, Column Position)" />
|
||||
<SpinBox id="column_pos" lw="mp" lh="wc" min-value="0" max-value="4" value="3" />
|
||||
</vbox>
|
||||
<vbox lw="0" lw8="0.25" lh="wc">
|
||||
<TextView lw="mp" lh="wc" text="@string(message, Message)" />
|
||||
<SpinBox id="message_pos" lw="mp" lh="wc" min-value="0" max-value="4" value="4" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
<hbox lw="wc" lh="wc" layout_gravity="right">
|
||||
<PushButton id="but_ok" text="@string(msg_box_ok, Ok)" icon="ok" margin-right="4dp" />
|
||||
<PushButton id="but_cancel" text="@string(camsg_box_cancel, Cancel)" icon="cancel" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
)xml";
|
||||
|
||||
mLayoutCont =
|
||||
getUISceneNode()->loadLayoutFromString( CUSTOM_OUTPUT_PARSER_XML, mContainer );
|
||||
|
||||
setTitle( i18n( "custom_output_parser", "Custom Output Parser" ) );
|
||||
|
||||
auto patternInput = find<UITextInput>( "custom_parser_pattern" );
|
||||
|
||||
mDataBindHolder += UIDataBindString::New( &mTmpCfg.pattern, patternInput );
|
||||
|
||||
UIDropDownList* cpTypeddl = find<UIDropDownList>( "custom_parser_type" );
|
||||
UIDataBind<ProjectOutputParserTypes>::Converter projectOutputParserTypesConverter(
|
||||
[]( const UIDataBind<ProjectOutputParserTypes>* databind, ProjectOutputParserTypes& val,
|
||||
const std::string& str ) -> bool {
|
||||
auto v = StyleSheetProperty( databind->getPropertyDefinition(), str ).asString();
|
||||
Uint32 idx;
|
||||
if ( String::fromString( idx, v ) && idx >= 0 && idx <= 2 ) {
|
||||
val = (ProjectOutputParserTypes)idx;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[cpTypeddl]( const UIDataBind<ProjectOutputParserTypes>*, std::string& str,
|
||||
const ProjectOutputParserTypes& val ) -> bool {
|
||||
str = cpTypeddl->getListBox()->getItem( (Uint32)val )->getText();
|
||||
return true;
|
||||
} );
|
||||
|
||||
mOptDb = UIDataBind<ProjectOutputParserTypes>::New(
|
||||
&mTmpCfg.type, cpTypeddl, projectOutputParserTypesConverter, "selected-index" );
|
||||
|
||||
mDataBindHolder +=
|
||||
UIDataBind<int>::New( &mTmpCfg.patternOrder.file, find<UIWidget>( "file_name_pos" ) );
|
||||
mDataBindHolder +=
|
||||
UIDataBind<int>::New( &mTmpCfg.patternOrder.line, find<UIWidget>( "line_number_pos" ) );
|
||||
mDataBindHolder +=
|
||||
UIDataBind<int>::New( &mTmpCfg.patternOrder.col, find<UIWidget>( "column_pos" ) );
|
||||
mDataBindHolder +=
|
||||
UIDataBind<int>::New( &mTmpCfg.patternOrder.message, find<UIWidget>( "message_pos" ) );
|
||||
|
||||
auto butOK = find<UIPushButton>( "but_ok" );
|
||||
butOK->setEnabled( !patternInput->getText().empty() );
|
||||
|
||||
patternInput->on( Event::OnTextChanged, [butOK, patternInput]( auto ) {
|
||||
butOK->setEnabled( !patternInput->getText().empty() );
|
||||
} );
|
||||
|
||||
butOK->onClick( [this]( auto ) {
|
||||
mCfg.pattern = mTmpCfg.pattern;
|
||||
mCfg.patternOrder = mTmpCfg.patternOrder;
|
||||
mCfg.type = mTmpCfg.type;
|
||||
sendCommonEvent( Event::OnConfirm );
|
||||
closeWindow();
|
||||
} );
|
||||
|
||||
find( "but_cancel" )->onClick( [this]( auto ) { closeWindow(); } );
|
||||
}
|
||||
|
||||
virtual ~UICustomOutputParserWindow() {}
|
||||
|
||||
protected:
|
||||
UIWidget* mLayoutCont{ nullptr };
|
||||
ProjectBuildOutputParserConfig mTmpCfg;
|
||||
ProjectBuildOutputParserConfig& mCfg;
|
||||
UIDataBindHolder mDataBindHolder;
|
||||
std::unique_ptr<UIDataBind<ProjectOutputParserTypes>> mOptDb;
|
||||
|
||||
virtual void onWindowReady() {
|
||||
forcedApplyStyle();
|
||||
|
||||
Sizef size( mLayoutCont->getSize() );
|
||||
setMinWindowSize( size );
|
||||
center();
|
||||
|
||||
if ( mShowWhenReady ) {
|
||||
mShowWhenReady = false;
|
||||
show();
|
||||
}
|
||||
|
||||
sendCommonEvent( Event::OnWindowReady );
|
||||
}
|
||||
};
|
||||
|
||||
class UIBuildStep : public UILinearLayout {
|
||||
public:
|
||||
static UIBuildStep* New( bool isBuildStep, UIBuildSettings* buildSettings, size_t stepNum,
|
||||
@@ -113,91 +303,106 @@ class UIBuildStep : public UILinearLayout {
|
||||
|
||||
static const auto SETTINGS_PANEL_XML = R"xml(
|
||||
<ScrollView lw="mp" lh="mp">
|
||||
<vbox lw="mp" lh="wc" class="settings_panel" id="build_settings_panel">
|
||||
<hbox lw="mp" lh="wc">
|
||||
<TextView lw="0" lw8="1" lh="wc" class="title" text="@string(build_settings, Build Settings)" />
|
||||
<PushButton id="build_del" lh="mp" text="@string(delete_setting, Delete Setting)" text-as-fallback="true" icon="icon(delete-bin, 12dp)" tooltip="@string(delete_setting, Delete Setting)" />
|
||||
</hbox>
|
||||
<Widget class="separator" lw="mp" lh="1dp" />
|
||||
<TextView class="subtitle" text="@string(build_name, Build Name)" />
|
||||
<Input id="build_name" lw="mp" lh="wc" text="new_name" />
|
||||
<TextView class="subtitle" text="@string(supported_platforms, Supported Platforms)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(supported_platforms_desc, Selecting none means that the build settings will work and be available on any Operating System)" />
|
||||
<StackLayout id="os_select" class="os_select" lw="wc" lh="wc">
|
||||
<CheckBox id="linux" text="Linux" />
|
||||
<CheckBox id="macos" text="macOS" />
|
||||
<CheckBox id="windows" text="Windows" />
|
||||
<CheckBox id="android" text="Android" />
|
||||
<CheckBox id="ios" text="iOS" />
|
||||
<CheckBox id="haiku" text="Haiku" />
|
||||
<CheckBox id="freebsd" text="FreeBSD" />
|
||||
<vbox lw="mp" lh="wc" class="settings_panel" id="build_settings_panel">
|
||||
<hbox lw="mp" lh="wc">
|
||||
<TextView lw="0" lw8="1" lh="wc" class="title" text="@string(build_settings, Build Settings)" />
|
||||
<PushButton id="build_del" lh="mp" text="@string(delete_setting, Delete Setting)" text-as-fallback="true" icon="icon(delete-bin, 12dp)" tooltip="@string(delete_setting, Delete Setting)" />
|
||||
</hbox>
|
||||
<Widget class="separator" lw="mp" lh="1dp" />
|
||||
<TextView class="subtitle" text="@string(build_name, Build Name)" />
|
||||
<Input id="build_name" lw="mp" lh="wc" text="new_name" />
|
||||
<TextView class="subtitle" text="@string(supported_platforms, Supported Platforms)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(supported_platforms_desc, Selecting none means that the build settings will work and be available on any Operating System)" />
|
||||
<StackLayout id="os_select" class="os_select" lw="wc" lh="wc">
|
||||
<CheckBox id="linux" text="Linux" />
|
||||
<CheckBox id="macos" text="macOS" />
|
||||
<CheckBox id="windows" text="Windows" />
|
||||
<CheckBox id="android" text="Android" />
|
||||
<CheckBox id="ios" text="iOS" />
|
||||
<CheckBox id="haiku" text="Haiku" />
|
||||
<CheckBox id="freebsd" text="FreeBSD" />
|
||||
</StackLayout>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="build_steps">
|
||||
<TextView class="subtitle" text="@string(build_steps, Build Steps)" />
|
||||
<vbox id="build_steps_cont" lw="mp" lh="wc"></vbox>
|
||||
<PushButton id="add_build_step" class="add_build_step" text="@string(add_build_step, Add Build Step)" />
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="clean_steps">
|
||||
<TextView class="subtitle" text="@string(clean_steps, Clean Steps)" />
|
||||
<vbox id="build_clean_steps_cont" lw="mp" lh="wc"></vbox>
|
||||
<PushButton id="add_clean_step" class="add_build_step" text="@string(add_clean_step, Add Clean Step)" />
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="build_types">
|
||||
<TextView class="subtitle" text="@string(build_types, Build Types)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(build_types_desc, Build types can be used as a dynamic build option represented by the special key ${build_type}. The build type can be switch easily from the editor.)" />
|
||||
<StackLayout class="build_types_cont span" lw="mp" lh="wc">
|
||||
<DropDownList id="build_type_list" layout_width="200dp" layout_height="wc" />
|
||||
<PushButton id="build_type_add" lh="mp" text="@string(add_build_type, Add Build Type)" tooltip="@string(add_build_type, Add Build Type)" text-as-fallback="true" icon="icon(add, 12dp)" />
|
||||
<PushButton id="build_type_del" lh="mp" text="@string(delete_selected, Delete Selected)" text-as-fallback="true" icon="icon(delete-bin, 12dp)" tooltip="@string(delete_selected, Delete Selected)" />
|
||||
</StackLayout>
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="build_steps">
|
||||
<TextView class="subtitle" text="@string(build_steps, Build Steps)" />
|
||||
<vbox id="build_steps_cont" lw="mp" lh="wc"></vbox>
|
||||
<PushButton id="add_build_step" class="add_build_step" text="@string(add_build_step, Add Build Step)" />
|
||||
</vbox>
|
||||
<vbox class="advanced_options" lw="mp" lh="wc">
|
||||
<hbox class="title advanced_options_title" lw="mp" lh="wc">
|
||||
<TextView enabled="false" lw="0" lw8="1" lh="wc" class="advance_opt" text="@string(advanced_options, Advanced Options)" />
|
||||
<Image enabled="false" lg="center" />
|
||||
</hbox>
|
||||
<vbox class="inner_box" lw="mp" lh="wc">
|
||||
<vbox lw="mp" lh="wc" class="custom_vars">
|
||||
<TextView class="subtitle" text="@string(custom_variables, Custom Variables)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc, "Custom Variables allow to simplify the build commands steps adding custom variables that can be used over the build settings in commands, arguments, and working directories.")' />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc_2, "Custom Variables can be invoked using ${variable_name} in any of the commands.)' />
|
||||
<hbox lw="mp" lh="wc">
|
||||
<TableView id="table_vars" lw="0" lw8="1" lh="150dp" />
|
||||
<vbox lw="wc" lh="mp" class="buttons_box">
|
||||
<PushButton id="custom_var_add" icon="icon(add, 12dp)" min-width="20dp" tooltip="@string(add_custom_variable, Add Custom Variable)" lg="center" />
|
||||
<PushButton id="custom_var_del" icon="icon(delete-bin, 12dp)" min-width="20dp" tooltip="@string(del_custom_variable, Delete Selected Variable)" lg="center" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
<TextView class="span" lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc_3, There are predefined custom variables available to use: ${project_root}: The folder / project root directory. ${build_type}: The build type selected to build the project. ${os}: The current operating system name. ${nproc}: The number of logical processing units.)' />
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="clean_steps">
|
||||
<TextView class="subtitle" text="@string(clean_steps, Clean Steps)" />
|
||||
<vbox id="build_clean_steps_cont" lw="mp" lh="wc"></vbox>
|
||||
<PushButton id="add_clean_step" class="add_build_step" text="@string(add_clean_step, Add Clean Step)" />
|
||||
</vbox>
|
||||
<vbox lw="mp" lh="wc" class="build_environment">
|
||||
<TextView class="subtitle" text="@string(build_environment, Build Environment)" />
|
||||
<CheckBox id="clear_sys_env" text="@string(clear_system_enviroment, Clear System Environment)" />
|
||||
<TextView class="subtitle" text="@string(custom_environment_variables, Custom Environment Variables)" />
|
||||
<hbox lw="mp" lh="wc">
|
||||
<TableView id="table_envs" lw="0" lw8="1" lh="150dp" />
|
||||
<vbox lw="wc" lh="mp" class="buttons_box">
|
||||
<PushButton id="custom_env_add" icon="icon(add, 12dp)" min-width="20dp" tooltip="@string(add_custom_variable, Add Custom Environment Variable)" lg="center" />
|
||||
<PushButton id="custom_env_del" icon="icon(delete-bin, 12dp)" min-width="20dp" tooltip="@string(del_custom_variable, Delete Selected Environment Variable)" lg="center" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="build_types">
|
||||
<TextView class="subtitle" text="@string(build_types, Build Types)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(build_types_desc, Build types can be used as a dynamic build option represented by the special key ${build_type}. The build type can be switch easily from the editor.)" />
|
||||
<StackLayout class="build_types_cont span" lw="mp" lh="wc">
|
||||
<DropDownList id="build_type_list" layout_width="200dp" layout_height="wc" />
|
||||
<PushButton id="build_type_add" lh="mp" text="@string(add_build_type, Add Build Type)" tooltip="@string(add_build_type, Add Build Type)" text-as-fallback="true" icon="icon(add, 12dp)" />
|
||||
<PushButton id="build_type_del" lh="mp" text="@string(delete_selected, Delete Selected)" text-as-fallback="true" icon="icon(delete-bin, 12dp)" tooltip="@string(delete_selected, Delete Selected)" />
|
||||
</StackLayout>
|
||||
</vbox>
|
||||
|
||||
<vbox class="advanced_options" lw="mp" lh="wc">
|
||||
<hbox class="title advanced_options_title" lw="mp" lh="wc">
|
||||
<TextView enabled="false" lw="0" lw8="1" lh="wc" class="advance_opt" text="@string(advanced_options, Advanced Options)" />
|
||||
<Image enabled="false" lg="center" />
|
||||
</hbox>
|
||||
<vbox class="inner_box" lw="mp" lh="wc">
|
||||
<vbox lw="mp" lh="wc" class="build_environment">
|
||||
<TextView class="subtitle" text="@string(build_environment, Build Environment)" />
|
||||
<CheckBox id="clear_sys_env" text="@string(clear_system_enviroment, Clear System Environment)" />
|
||||
<TextView class="subtitle" text="@string(custom_environment_variables, Custom Environment Variables)" />
|
||||
<TableView id="table_envs" lw="mp" lh="150dp" />
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="output_parser">
|
||||
<TextView class="subtitle" text="@string(output_parser, Output Parser)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(output_parser_desc, Custom output parsers scan command line output for user-provided error patterns to create entries in Issues and highlight those errors on the Build Output)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(output_parser_preset, "Presets are provided as generic output parsers, you can select one below, by default a \"generic\" preset will be selected:")' />
|
||||
<DropDownList id="output_parsers_presets_list" layout_width="200dp" layout_height="wc">
|
||||
<item></item>
|
||||
<item>generic</item>
|
||||
</DropDownList>
|
||||
<PushButton class="output_parser_custom_rule span" text="@string(output_parser_custom_rule, Add Custom Rule)" />
|
||||
<hbox class="output_parser_rules" lw="mp" lh="wc">
|
||||
<TextView lw="0" lw8="0.2" lh="wc" class="type" text="@string(type, Type)" />
|
||||
<TextView lw="0" lw8="0.8" lh="wc" class="pattern" class="rule" text="@string(pattern, Pattern)" />
|
||||
<PushButton class="remove_item" text="@string(remove item, Remove Item)" text-as-fallback="true" icon="icon(delete-bin, 12dp)" tooltip="@string(remove_item, Remove Item)" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<vbox lw="mp" lh="wc" class="custom_vars">
|
||||
<TextView class="subtitle" text="@string(custom_variables, Custom Variables)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc, "Custom Variables allow to simplify the build commands steps adding custom variables that can be used over the build settings in commands, arguments, and working directories.")' />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc_2, "Custom Variables can be invoked using ${variable_name} in any of the commands.)' />
|
||||
<TableView id="table_vars" lw="mp" lh="150dp" />
|
||||
<TextView class="span" lw="mp" lh="wc" word-wrap="true" text='@string(custom_variables_desc_3, There are predefined custom variables available to use: ${project_root}: The folder / project root directory. ${build_type}: The build type selected to build the project. ${os}: The current operating system name. ${nproc}: The number of logical processing units.)' />
|
||||
</vbox>
|
||||
<vbox lw="mp" lh="wc" class="output_parser">
|
||||
<TextView class="subtitle" text="@string(output_parser, Output Parser)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text="@string(output_parser_desc, Custom output parsers scan command line output for user-provided error patterns to create entries in Issues and highlight those errors on the Build Output)" />
|
||||
<TextView lw="mp" lh="wc" word-wrap="true" text='@string(output_parser_preset, "Presets are provided as generic output parsers, you can select one below, by default a \"generic\" preset will be selected:")' />
|
||||
<DropDownList id="output_parsers_presets_list" layout_width="200dp" layout_height="wc">
|
||||
<item></item>
|
||||
<item>generic</item>
|
||||
</DropDownList>
|
||||
<hbox lw="mp" lh="wc">
|
||||
<TableView id="table_output_parsers" lw="0" lw8="1" lh="150dp" />
|
||||
<vbox lw="wc" lh="mp" class="buttons_box">
|
||||
<PushButton id="custom_op_add" icon="icon(add, 12dp)" min-width="20dp" tooltip="@string(add_custom_output_parser, Add Custom Output Parser)" lg="center" />
|
||||
<PushButton id="custom_op_edit" icon="icon(file-edit, 12dp)" min-width="20dp" tooltip="@string(edit_custom_output_parser, Edit Selected Custom Output Parser)" lg="center" />
|
||||
<PushButton id="custom_op_del" icon="icon(delete-bin, 12dp)" min-width="20dp" tooltip="@string(del_custom_output_parser, Delete Selected Custom Output Parser)" lg="center" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
</vbox>
|
||||
|
||||
<TextView class="build_settings_clarification span" word-wrap="true" lw="mp" lh="wc" text='@string(build_settings_save_clarification, * All changes are automatically saved)' />
|
||||
</vbox>
|
||||
</ScrollView>
|
||||
|
||||
<TextView class="build_settings_clarification span" word-wrap="true" lw="mp" lh="wc" text='@string(build_settings_save_clarification, * All changes are automatically saved)' />
|
||||
</vbox>
|
||||
</ScrollView>
|
||||
)xml";
|
||||
|
||||
UIBuildSettings* UIBuildSettings::New( ProjectBuild& build, ProjectBuildConfiguration& config ) {
|
||||
@@ -303,40 +508,19 @@ UIBuildSettings::UIBuildSettings( ProjectBuild& build, ProjectBuildConfiguration
|
||||
}
|
||||
|
||||
auto advTitle = querySelector( ".settings_panel > .advanced_options > .title" );
|
||||
advTitle->onClick( [this]( const MouseEvent* event ) {
|
||||
auto img = event->getNode()->findByType( UI_TYPE_IMAGE )->asType<UIWidget>();
|
||||
findByClass( "inner_box" )->toggleClass( "visible" );
|
||||
img->toggleClass( "expanded" );
|
||||
advTitle->onClick( [this, advTitle]( const MouseEvent* event ) {
|
||||
if ( getEventDispatcher()->getMouseDownNode() == advTitle ) {
|
||||
auto img = event->getNode()->findByType( UI_TYPE_IMAGE )->asType<UIWidget>();
|
||||
findByClass( "inner_box" )->toggleClass( "visible" );
|
||||
img->toggleClass( "expanded" );
|
||||
}
|
||||
} );
|
||||
|
||||
mDataBindHolder +=
|
||||
UIDataBindBool::New( &mBuild.mConfig.clearSysEnv, find<UIWidget>( "clear_sys_env" ) );
|
||||
|
||||
UITableView* tableEnvs = find<UITableView>( "table_vars" );
|
||||
auto modelEnvs = ItemPairListModel<std::string, std::string>::create( mBuild.mEnvs );
|
||||
modelEnvs->setIsEditable( true );
|
||||
modelEnvs->setColumnName( 0, getTranslatorString( "env_name", "Name" ) );
|
||||
modelEnvs->setColumnName( 1, getTranslatorString( "env_value", "Value" ) );
|
||||
tableEnvs->setAutoColumnsWidth( true );
|
||||
tableEnvs->setModel( modelEnvs );
|
||||
tableEnvs->setEditable( true );
|
||||
tableEnvs->setEditTriggers( UIAbstractView::EditTrigger::DoubleClicked );
|
||||
tableEnvs->onCreateEditingDelegate = []( const ModelIndex& ) {
|
||||
return StringModelEditingDelegate::New();
|
||||
};
|
||||
|
||||
UITableView* tableVars = find<UITableView>( "table_vars" );
|
||||
auto modelVars = ItemPairListModel<std::string, std::string>::create( mBuild.mVars );
|
||||
modelVars->setColumnName( 0, getTranslatorString( "var_name", "Name" ) );
|
||||
modelVars->setColumnName( 1, getTranslatorString( "var_value", "Value" ) );
|
||||
modelVars->setIsEditable( true );
|
||||
tableVars->setAutoColumnsWidth( true );
|
||||
tableVars->setModel( modelVars );
|
||||
tableVars->setEditable( true );
|
||||
tableVars->setEditTriggers( UIAbstractView::EditTrigger::DoubleClicked );
|
||||
tableVars->onCreateEditingDelegate = []( const ModelIndex& ) {
|
||||
return StringModelEditingDelegate::New();
|
||||
};
|
||||
bindTable( "table_envs", "env", mBuild.mEnvs );
|
||||
bindTable( "table_vars", "var", mBuild.mVars );
|
||||
|
||||
find( "build_type_add" )->onClick( [this, buildTypeDropDown, panelBuildTypeDDL]( auto ) {
|
||||
UIMessageBox* msgBox =
|
||||
@@ -393,6 +577,42 @@ UIBuildSettings::UIBuildSettings( ProjectBuild& build, ProjectBuildConfiguration
|
||||
ProjectBuildOutputParser::getPresets()[mBuild.mOutputParser.mPreset].mConfig;
|
||||
}
|
||||
} );
|
||||
|
||||
UITableView* tableOP = find<UITableView>( "table_output_parsers" );
|
||||
tableOP->setAutoColumnsWidth( true );
|
||||
tableOP->setFitAllColumnsToWidget( true );
|
||||
auto modelOP = OutputParserModel::create( mBuild.mOutputParser.mConfig,
|
||||
[this]( auto s, auto s2 ) { return i18n( s, s2 ); } );
|
||||
tableOP->setModel( modelOP );
|
||||
|
||||
find( "custom_op_add" )->onClick( [this, modelOP]( auto ) {
|
||||
mTmpOpCfg = {};
|
||||
auto ret = UICustomOutputParserWindow::New( mTmpOpCfg );
|
||||
ret->showWhenReady();
|
||||
ret->on( Event::OnConfirm, [this, modelOP]( auto ) {
|
||||
mBuild.mOutputParser.mConfig.push_back( mTmpOpCfg );
|
||||
modelOP->invalidate();
|
||||
} );
|
||||
} );
|
||||
|
||||
find( "custom_op_edit" )->onClick( [this, tableOP, modelOP]( auto ) {
|
||||
if ( !tableOP->getSelection().isEmpty() && tableOP->getSelection().first().row() >= 0 &&
|
||||
tableOP->getSelection().first().row() < (int)mBuild.mOutputParser.mConfig.size() ) {
|
||||
auto ret = UICustomOutputParserWindow::New(
|
||||
mBuild.mOutputParser.mConfig[tableOP->getSelection().first().row()] );
|
||||
ret->showWhenReady();
|
||||
ret->on( Event::OnConfirm, [modelOP]( auto ) { modelOP->invalidate(); } );
|
||||
}
|
||||
} );
|
||||
|
||||
find( "custom_op_del" )->onClick( [this, tableOP, modelOP]( auto ) {
|
||||
if ( !tableOP->getSelection().isEmpty() && tableOP->getSelection().first().row() >= 0 &&
|
||||
tableOP->getSelection().first().row() < (int)mBuild.mOutputParser.mConfig.size() ) {
|
||||
mBuild.mOutputParser.mConfig.erase( mBuild.mOutputParser.mConfig.begin() +
|
||||
tableOP->getSelection().first().row() );
|
||||
modelOP->invalidate();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
void UIBuildSettings::updateOS() {
|
||||
@@ -424,6 +644,45 @@ void UIBuildSettings::refreshTab() {
|
||||
mTab->setId( "build_settings_" + mBuild.mName );
|
||||
}
|
||||
|
||||
void UIBuildSettings::bindTable( const std::string& name, const std::string& key,
|
||||
ProjectBuildKeyVal& data ) {
|
||||
|
||||
const auto createInputDelegate = []( const ModelIndex& ) -> ModelEditingDelegate* {
|
||||
auto delegate = StringModelEditingDelegate::New();
|
||||
delegate->onWillBeginEditing = [delegate]() {
|
||||
delegate->getWidget()->asType<UITextInput>()->on(
|
||||
Event::OnFocusLoss, [delegate]( auto ) { delegate->onCommit(); } );
|
||||
};
|
||||
return delegate;
|
||||
};
|
||||
|
||||
UITableView* table = find<UITableView>( name );
|
||||
auto model = ItemPairListModel<std::string, std::string>::create( data );
|
||||
model->setColumnName( 0, getTranslatorString( key + "_name", "Name" ) );
|
||||
model->setColumnName( 1, getTranslatorString( key + "_value", "Value" ) );
|
||||
model->setIsEditable( true );
|
||||
table->setAutoColumnsWidth( true );
|
||||
table->setFitAllColumnsToWidget( true );
|
||||
table->setModel( model );
|
||||
table->setEditable( true );
|
||||
table->setSelectionType( UIAbstractView::SelectionType::Cell );
|
||||
table->setEditTriggers( UIAbstractView::EditTrigger::DoubleClicked |
|
||||
UIAbstractTableView::EditTrigger::EditKeyPressed );
|
||||
table->onCreateEditingDelegate = createInputDelegate;
|
||||
|
||||
find<UIPushButton>( "custom_" + key + "_add" )->onClick( [this, model, &data]( auto ) {
|
||||
data.push_back( { i18n( "new_name", "New Name" ), i18n( "new_value", "New Value" ) } );
|
||||
model->invalidate();
|
||||
} );
|
||||
|
||||
find<UIPushButton>( "custom_" + key + "_del" )->onClick( [model, table, &data]( auto ) {
|
||||
if ( !table->getSelection().isEmpty() ) {
|
||||
data.erase( data.begin() + table->getSelection().first().row() );
|
||||
model->invalidate();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
void UIBuildSettings::moveStepUp( size_t stepNum, bool isClean ) {
|
||||
moveStepDir( stepNum, isClean, -1 );
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ class UIBuildSettings : public UIRelativeLayout {
|
||||
UITab* mTab{ nullptr };
|
||||
String mOldName;
|
||||
std::unordered_map<UIWidget*, std::vector<Uint32>> mCbs;
|
||||
ProjectBuildOutputParserConfig mTmpOpCfg;
|
||||
|
||||
explicit UIBuildSettings( ProjectBuild& build, ProjectBuildConfiguration& config );
|
||||
|
||||
@@ -42,6 +43,8 @@ class UIBuildSettings : public UIRelativeLayout {
|
||||
void updateOS();
|
||||
|
||||
void refreshTab();
|
||||
|
||||
void bindTable( const std::string& name, const std::string& key, ProjectBuildKeyVal& data );
|
||||
};
|
||||
|
||||
} // namespace ecode
|
||||
|
||||
Reference in New Issue
Block a user