changeset 2825:69e144d81f19

iOS: Rewrite DWContainer to use a single DWTableViewCell per row. Previously a cell was allocated for each row's column. Instead save an array of NSString and UIImages which can be displayed in the custom UITableViewCell based on the DW_FEATURE_CONTAINER_MODE setting.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 17 Aug 2022 11:36:34 +0000
parents 22327163b35c
children 5f0483eb39a4
files ios/dw.m
diffstat 1 files changed, 83 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/ios/dw.m	Tue Aug 16 17:24:29 2022 +0000
+++ b/ios/dw.m	Wed Aug 17 11:36:34 2022 +0000
@@ -2333,15 +2333,22 @@
 /* Subclass UITableViewCell so we can support multiple columns...
  * Enabled via the DW_FEATURE_CONTAINER_MODE feature setting.
  */
-@interface DWTableViewCell : UITableViewCell {}
+@interface DWTableViewCell : UITableViewCell
+{
+    NSMutableArray *columndata;
+}
+-(void)setColumnData:(NSMutableArray *)input;
+-(NSMutableArray *)columnData;
 @end
 
 @implementation DWTableViewCell
--(void)dealloc { [super dealloc]; }
+-(void)setColumnData:(NSMutableArray *)input { [columndata release]; columndata = input; [columndata retain]; }
+-(NSMutableArray *)columnData { return columndata; }
+-(void)dealloc { [columndata release]; [super dealloc]; }
 @end
 
  /* Create a tableview cell for containers using DW_CONTAINER_MODE_* or listboxes */
-DWTableViewCell *_dw_table_cell_view_new(UIImage *icon, NSString *text)
+DWTableViewCell *_dw_table_cell_view_new(UIImage *icon, NSString *text, NSMutableArray *columndata)
 {
     DWTableViewCell *browsercell = [[DWTableViewCell alloc] init];
     [browsercell setAutoresizesSubviews:YES];
@@ -2350,6 +2357,8 @@
         [[browsercell imageView] setImage:icon];
     if(text)
         [[browsercell textLabel] setText:text];
+    if(columndata)
+        [browsercell setColumnData:columndata];
     return browsercell;
 }
 
@@ -2380,13 +2389,14 @@
 -(void)setUserdata:(void *)input;
 -(void)setFilesystem:(int)input;
 -(int)filesystem;
--(int)addRow:(NSArray *)input;
+-(int)addRow:(DWTableViewCell *)input;
 -(int)addRows:(int)number;
--(void)editCell:(id)input at:(int)row and:(int)col;
+-(void)editCell:(id)input at:(int)row;
 -(void)removeRow:(int)row;
 -(void)setRow:(int)row title:(const char *)input;
 -(void *)getRowTitle:(int)row;
--(id)getRow:(int)row and:(int)col;
+-(id)getRow:(int)row;
+-(NSMutableArray *)getColumns;
 -(int)cellType:(int)col;
 -(int)lastAddPoint;
 -(int)lastQueryPoint;
@@ -2402,18 +2412,13 @@
 {
     /* Ignoring section for now, everything in one section */
     if(tvcols && data)
-    {
-        int cols = (int)[tvcols count];
-        int total = (int)[data count];
-        if(cols && total)
-            return total / cols;
-    }
+        return [data count];
     return 0;
 }
 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
     /* Not reusing cell views, so get the cell from our array */
-    int index = (int)(indexPath.row * [tvcols count]);
+    int index = (int)indexPath.row;
     id celldata = [data objectAtIndex:index];
 
     /* The data is already a NSTableCellView so just return that */
@@ -2520,30 +2525,27 @@
         [self refreshColors];
 }
 -(void)viewDidChangeEffectiveAppearance { [self checkDark]; }
--(int)insertRow:(NSArray *)input at:(int)index
+-(int)insertRow:(DWTableViewCell *)input at:(int)index
 {
     if(data)
     {
-        unsigned long start = [tvcols count] * index;
-        NSIndexSet *set = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(start, start + [tvcols count])];
         if(index < iLastAddPoint)
         {
             iLastAddPoint++;
         }
-        [data insertObjects:input atIndexes:set];
+        [data insertObject:input atIndex:index];
         [titles insertPointer:NULL atIndex:index];
         [rowdatas insertPointer:NULL atIndex:index];
-        [set release];
         return (int)[titles count];
     }
     return 0;
 }
--(int)addRow:(NSArray *)input
+-(int)addRow:(DWTableViewCell *)input
 {
     if(data)
     {
         iLastAddPoint = (int)[titles count];
-        [data addObjectsFromArray:input];
+        [data addObject:input];
         [titles addPointer:NULL];
         [rowdatas addPointer:NULL];
         return (int)[titles count];
@@ -2554,17 +2556,13 @@
 {
     if(tvcols)
     {
-        int count = (int)(number * [tvcols count]);
         int z;
 
         iLastAddPoint = (int)[titles count];
 
-        for(z=0;z<count;z++)
+        for(z=0;z<number;z++)
         {
             [data addObject:[NSNull null]];
-        }
-        for(z=0;z<number;z++)
-        {
             [titles addPointer:NULL];
             [rowdatas addPointer:NULL];
         }
@@ -2572,16 +2570,15 @@
     }
     return 0;
 }
--(void)editCell:(id)input at:(int)row and:(int)col
+-(void)editCell:(id)input at:(int)row
 {
     if(tvcols)
     {
-        int index = (int)(row * [tvcols count]) + col;
-        if(index < [data count])
+        if(row < [data count])
         {
             if(!input)
                 input = [NSNull null];
-            [data replaceObjectAtIndex:index withObject:input];
+            [data replaceObjectAtIndex:row withObject:input];
         }
     }
 }
@@ -2589,17 +2586,9 @@
 {
     if(tvcols)
     {
-        int z, start, end;
-        int count = (int)[tvcols count];
         void *oldtitle;
 
-        start = (count * row);
-        end = start + count;
-
-        for(z=start;z<end;z++)
-        {
-            [data removeObjectAtIndex:start];
-        }
+        [data removeObjectAtIndex:row];
         oldtitle = [titles pointerAtIndex:row];
         [titles removePointerAtIndex:row];
         [rowdatas removePointerAtIndex:row];
@@ -2625,7 +2614,8 @@
 -(void)setRowData:(int)row title:(void *)input { if(rowdatas && input) { [rowdatas replacePointerAtIndex:row withPointer:input]; } }
 -(void *)getRowTitle:(int)row { if(titles && row > -1) { return [titles pointerAtIndex:row]; } return NULL; }
 -(void *)getRowData:(int)row { if(rowdatas && row > -1) { return [rowdatas pointerAtIndex:row]; } return NULL; }
--(id)getRow:(int)row and:(int)col { if(data && [data count]) { int index = (int)(row * [tvcols count]) + col; return [data objectAtIndex:index]; } return nil; }
+-(id)getRow:(int)row { if(data && [data count]) {  return [data objectAtIndex:row]; } return nil; }
+-(NSMutableArray *)getColumns { return tvcols; }
 -(int)cellType:(int)col { return [[types objectAtIndex:col] intValue]; }
 -(int)lastAddPoint { return iLastAddPoint; }
 -(int)lastQueryPoint { return iLastQueryPoint; }
@@ -5544,9 +5534,8 @@
     {
         DWContainer *cont = handle;
         NSString *nstr = [NSString stringWithUTF8String:text];
-        NSArray *newrow = [NSArray arrayWithObject:_dw_table_cell_view_new(nil, nstr)];
-
-        [cont addRow:newrow];
+
+        [cont addRow:_dw_table_cell_view_new(nil, nstr, nil)];
         [cont reloadData];
         [cont setNeedsDisplay];
     }
@@ -5578,9 +5567,8 @@
     {
         DWContainer *cont = handle;
         NSString *nstr = [NSString stringWithUTF8String:text];
-        NSArray *newrow = [NSArray arrayWithObject:_dw_table_cell_view_new(nil, nstr)];
-
-        [cont insertRow:newrow at:pos];
+
+        [cont insertRow:_dw_table_cell_view_new(nil, nstr, nil) at:pos];
         [cont reloadData];
         [cont setNeedsDisplay];
     }
@@ -5622,9 +5610,8 @@
         for(z=0;z<count;z++)
         {
             NSString *nstr = [NSString stringWithUTF8String:text[z]];
-            NSArray *newrow = [NSArray arrayWithObjects:_dw_table_cell_view_new(nil, nstr),nil];
-
-            [cont addRow:newrow];
+
+            [cont addRow:_dw_table_cell_view_new(nil, nstr, nil)];
         }
         [cont reloadData];
         [cont setNeedsDisplay];
@@ -5751,7 +5738,7 @@
         }
         else
         {
-            DWTableViewCell *cell = [cont getRow:index and:0];
+            DWTableViewCell *cell = [cont getRow:index];
             NSString *nstr = [[cell textLabel] text];
 
             strncpy(buffer, [nstr UTF8String], length - 1);
@@ -5789,7 +5776,7 @@
         if(index <= count)
         {
             NSString *nstr = [NSString stringWithUTF8String:buffer];
-            DWTableViewCell *cell = [cont getRow:index and:0];
+            DWTableViewCell *cell = [cont getRow:index];
 
             [[cell textLabel] setText:nstr];
             [cont reloadData];
@@ -7182,7 +7169,7 @@
         else if(type & DW_CFA_STRING)
         {
             char *str = *((char **)data);
-            text = [ NSString stringWithUTF8String:str ];
+            text = [NSString stringWithUTF8String:str];
         }
         else
         {
@@ -7199,7 +7186,7 @@
                 struct tm curtm;
                 CDATE cdate = *((CDATE *)data);
 
-                memset( &curtm, 0, sizeof(curtm) );
+                memset(&curtm, 0, sizeof(curtm));
                 curtm.tm_mday = cdate.day;
                 curtm.tm_mon = cdate.month - 1;
                 curtm.tm_year = cdate.year - 1900;
@@ -7219,24 +7206,53 @@
                 strftime(textbuffer, 100, "%X", &curtm);
             }
             if(textbuffer[0])
-                text = [ NSString stringWithUTF8String:textbuffer ];
-        }
-    }
-
-    id object = [cont getRow:(row+lastadd) and:column];
-    
+                text = [NSString stringWithUTF8String:textbuffer];
+        }
+    }
+
+    id object = [cont getRow:(row+lastadd)];
+    NSUInteger capacity = [[cont getColumns] count];
+
     /* If it is a cell, change the content of the cell */
     if([object isMemberOfClass:[DWTableViewCell class]])
     {
         DWTableViewCell *cell = object;
 
-        if(icon)
-            [[cell imageView] setImage:icon];
-        else
-            [[cell textLabel] setText:text];
-    }
-    else /* Otherwise replace it with a new cell */
-        [cont editCell:_dw_table_cell_view_new(icon, text) at:(row+lastadd) and:column];
+        if(column == 0)
+        {
+            if(icon)
+                [[cell imageView] setImage:icon];
+            else
+                [[cell textLabel] setText:text];
+        }
+        else if(icon || text)
+        {
+            NSMutableArray *cd = [cell columnData];
+
+            if(column >= capacity)
+                capacity = column + 1;
+
+            if(!cd)
+            {
+                cd = [NSMutableArray arrayWithCapacity:capacity];
+                [cell setColumnData:cd];
+            }
+            if(cd)
+            {
+                while([cd count] <= column)
+                    [cd addObject:[NSNull null]];
+                [cd replaceObjectAtIndex:column withObject:(text ? text : icon)];
+            }
+        }
+    }
+    else
+    {
+        NSMutableArray *cd  = [NSMutableArray arrayWithCapacity:(capacity > column ? capacity : column + 1)];
+        if(cd)
+            [cd replaceObjectAtIndex:column withObject:(text ? text : icon)];
+        /* Otherwise replace it with a new cell */
+        [cont editCell:_dw_table_cell_view_new(icon, text, cd) at:(row+lastadd)];
+    }
     [cont setNeedsDisplay];
     DW_FUNCTION_RETURN_NOTHING;
 }
@@ -7304,7 +7320,7 @@
     if(pointer)
         lastadd = [cont lastAddPoint];
 
-    id object = [cont getRow:(row+lastadd) and:0];
+    id object = [cont getRow:(row+lastadd)];
     
     /* If it is a cell, change the content of the cell */
     if([object isMemberOfClass:[DWTableViewCell class]])
@@ -7317,7 +7333,7 @@
             [[cell textLabel] setText:text];
     }
     else /* Otherwise replace it with a new cell */
-        [cont editCell:_dw_table_cell_view_new(icon, text) at:(row+lastadd) and:0];
+        [cont editCell:_dw_table_cell_view_new(icon, text, nil) at:(row+lastadd)];
     [cont setNeedsDisplay];
     DW_FUNCTION_RETURN_NOTHING;
 }