имплементнах бутоните за сортиране по колона (2) от фигурата:
тестовата таблица се чете запис по запис от CSV файл, докато се рисува и обработва инпута. сортират се само записите което автоматично води до пренареждане на контролите. полетата могат да се анимират. и трите неща не са тривиални в retained mode. кода е съвсем малко.
тук е оригиналното видео ако някой иска да гледа анимациите с 60 херца:
Код: Избери всички
static void UI_RecordField_wg( v2_t position, v2_t size, v2_t separatorThickness, const char *field, int handle ) {
v2_t sz = v2Sub( size, separatorThickness );
UI_RightText_wg( position, sz, field, handle );
}
void UI_Record_wg( v2_t position,
v2_t size,
v2_t separatorThickness,
int numFields,
const float fieldSeparators[],
char * const fields[],
int handle ) {
// handle input in the separators between cells too
UI_ClickRect_wg( position, size, handle );
v2_t fieldPosition = position;
int i;
for ( i = 0; i < numFields - 1; i++ ) {
float step = fieldSeparators[i] * size.x;
UI_RecordField_wg( fieldPosition, v2xy( step, size.y ), separatorThickness, fields[i], handle );
fieldPosition.x += step;
}
// the last cell goes to the end of the record
UI_RecordField_wg( fieldPosition, v2xy( Maxf( 0, ( position.x + size.x ) - fieldPosition.x ), size.y ), separatorThickness, fields[i], handle );
}
Код: Избери всички
table_t tabs[MAX_TABS] = {
{
.columnNames = { "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", },
.columnIsNum = { true, false, false, true, true, true, true },
.columnSeparators = { 0.125, 0.125, 0.15, 0.15, 0.15, 0.15 },
},
...
}
всеки кадър...
Код: Избери всички
table_t *table = &tabs[currentTab];
// TODO: use different csv file per tab
// read one record per frame from a CSV file
UpdateRead( va( "%stest.csv", SYS_AppDir() ), &table->numRecords, &table->records );
// table header buttons
UI_WidgetsContext( rt_pixel,
RT_FONT_SZ_PIXEL,
2,
colorrgb( 0, 0.2, 0.2 ),
colorrgb( 0, 0.5, 0.5 ),
colorrgb( 0, 1, 1 ) );
v2_t buttonPosition = framePosition;
for ( int column = 0; column < table->numColumns; column++ ) {
float x = NextButtonX( column, table->numColumns, framePosition, buttonPosition, table->columnSeparators, headerSize );
v2_t buttonSize = v2xy( x, headerSize.y );
if ( UI_RightTextButton_l( buttonPosition,
v2Sub( buttonSize, separatorThickness ),
table->columnNames[column],
column ) ) {
// on click, either animate table or just sort
if ( VAR_Num( enableTableAnim ) ) {
sortColumn = column;
RecStartAnimToSide( table->numRecords, table->records, recordSize, recordsPosition );
} else {
RecSort( table->numRecords, table->records, table->columnIsNum[column], column );
}
}
buttonPosition.x += buttonSize.x;
}
// list of records
UI_WidgetsContext( rt_pixelBD,
RT_FONT_SZ_PIXEL_BD,
1,
colorrgb( 0, 0.3, 0.3 ),
colorrgb( 0, 0.7, 0.7 ),
colorrgb( 0, 1, 1 ) );
v2_t linePosition = recordsPosition;
bool_t animFinished = false;
for ( int i = 0; i < table->numRecords; i++ ) {
record_t *rec = &table->records[i];
v2_t animatedPosition = RecUpdateAnimation( rec, linePosition, &animFinished );
UI_Record_l( animatedPosition,
recordSize,
separatorThickness,
table->numColumns,
table->columnSeparators,
table->records[i].fields,
i );
linePosition.y += recordSize.y;
}
// if the last record animation has stopped, sort records, launch next animation
if ( VAR_Num( enableTableAnim ) && animFinished ) {
RecSort( table->numRecords, table->records, table->columnIsNum[sortColumn], sortColumn );
RecStartAnimUp( table->numRecords, table->records, recordSize, recordsPosition );
}