Data Grid

Previous topic - Next topic

aonyn

Hi Gernot,

Sorry, I know this is a code snippets forum, and not feature request, however, I did not know where to post this because it is for DDGui.

Would it be possible to add a Data Grid widget to DDGui. (similar to an excel spreadsheet grid)?

This would be a very useful widget for me.

Thanks,
Dave Marconi
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

Kitty Hello

I thought of that once, too.
It's really a nice idea.

However!! With the current DDgui you can make user widgets very easily.

Code (glbasic) Select

// a callback for a user defined spinner element
FUNCTION SpinnerFkt: id$, verb$, BYREF info$
SELECT verb$
CASE "DRAW"
// get size of widget
LOCAL w%, h%
w=DDgui_get(id$, "WIDTH")
h=DDgui_get(id$, "HEIGHT")
DRAWRECT 0,0,w,h, RGB(0xc0, 0xc0, 0xc0)
PRINT "  ^",0,0
PRINT "#" + DDgui_get(id$, "TEXT"),0,16
PRINT "  v",0,32
CASE "CLICKED" // mouse button up (1) or down (-1)
IF DDgui_get(id$, "CLICKED") // a-ha - clicked
// info$ = "XXXX,YYYY,BB" - fixed length string with local coords and button state
LOCAL mx% = MID$(info$,0,4)
LOCAL my% = MID$(info$,5,4)
LOCAL b1% = MID$(info$,10,2)

IF b1=1 // button up
IF my<16 // "up"
LOCAL num% = DDgui_get(id$, "TEXT")
INC num
DDgui_set(id$, "TEXT", num)
ELSEIF my>32
LOCAL num% = DDgui_get(id$, "TEXT")
DEC num
DDgui_set(id$, "TEXT", num)
ENDIF
ENDIF
ENDIF
CASE "INIT" // allocate memory/types/load images/...
DDgui_set(id$, "WIDTH", 64)
DDgui_set(id$, "HEIGHT", 48)
CASE "DESTROY" // free memroy
ENDSELECT
ENDFUNCTION



FUNCTION TestUser:
DDgui_pushdialog(0,0,400,400,TRUE)
DDgui_set("", "TEXT", "User widgets")
DDgui_spacer()
DDgui_set("", "MOVEABLE", TRUE)
DDgui_set("", "SCALEABLE", TRUE)
DDgui_widget("", "a simple spinner")
LOCAL foo AS DDgui_userfunction
foo = SpinnerFkt
DDgui_user("u_spin1", "SPINNER", foo, 0,0)
DDgui_user("u_spin2", "SPINNER", foo, 0,0)

WHILE TRUE
DDgui_show(TRUE)
SHOWSCREEN
WEND
ENDFUNCTION


The main problem might be to have the looks of DDgui now. But you can use the DDgui draing functions - just peek at how I am drawing text DDgui_print_internal (IIRC).

Do you think you can make it?
You can keep a type-reference with a 2D array for the cells in the widget.


aonyn

Hi Gernot,

Thanks. I will look at the sample code you provided, and give it a try.
I may show you what I come up with and have you help me optimize it if you don't mind.
Then of course it would be posted here for everyone who wants to use it.

Regards,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

Slydog

#3
Here's something I started, it's just a basic skeleton, nothing tested of course!

Code (glbasic) Select
TYPE TGridCell
text$ = ""
rgbBack% = RGB(255,255,255)
rgbFore% = RGB(0,0,0)
isEditable% = TRUE
ENDTYPE

TYPE TGrid
cells[][] AS TGridCell
columnWidths%[]
rowHeight% = 20
selectedCellX% = -1
selectedCellY% = -1

FUNCTION Set: sizeX%, sizeY%
DIM self.cells[sizeX][sizeY]
DIM self.columnWidths[sizeY]

// Set default column widths
FOR column = 0 TO sizeY-1
self.columnWidths[column] = 40 // Default column width
NEXT
ENDFUNCTION

FUNCTION SetColumnWidth: column%, width%
self.columnWidths[column] = width
ENDFUNCTION

FUNCTION CellText: x%, y%, text$
self.cells[x][y].text$ = text$
ENDFUNCTION

FUNCTION CellFore: x%, y%, rgbFore%
self.cells[x][y].rgbFore = rgbFore
ENDFUNCTION

FUNCTION CellBack: x%, y%, rgbBack%
self.cells[x][y].rgbBack = rgbBack
ENDFUNCTION

FUNCTION CellEditable: x%, y%, isEditable%
self.cells[x][y].isEditable = isEditable
ENDFUNCTION

// Call once per frame to determine which cell is selected, if any
FUNCTION UpdateSelected:
// Get mouse pos

// Determine what row mouse is in
// IF mouse not within grid's width
// self.selectedCellX = -1
// self.selectedCellY = -1
//     RETURN
// ELSE
//     self.selectedCellX = ...
// ENDIF

// Determine what column mouse is in
// IF mouse not within grid's height
// self.selectedCellX = -1
// self.selectedCellY = -1
//     RETURN
// ELSE
//     self.selectedCellY = ...
// ENDIF
ENDFUNCTION

FUNCTION Draw:
LOCAL x%, y%
FOR x = 0 TO BOUNDS(self.cells[], 0)
FOR y = 0 TO BOUNDS(self.cells[], 1)
// Draw cell
NEXT
NEXT
ENDFUNCTION

ENDTYPE
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

aonyn

Thanks Slydog,

This definitely helps give me somewhere to begin.

I assume since you posted this, you don't mind if I use it directly in my code if it works out for me, and post it back here later?

Thanks,
Dave
For by grace are ye saved through faith, and that not of yourselves: it is the gift of God: Not of works, lest any man should boast. -Ephesians 2:8-9

Slydog

Sure, go ahead.
I wasn't sure how to handle the 'selected' cell, so I hope what I have can work.
My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

Kitty Hello

for the selection on touchscreen devices: Get a mouse down position _and_ time!!
Then when the mouse moves, check what time delay between the last up-lift and re-tap was. If it's quite short, use the select-cells method. Otherwise use left mouse button to scroll.
Or use 2 fingers to scroll and one to select.