Jump to content
Sting

Widget Repository

Recommended Posts

Is there a place where users can post widgets that they make?  I either need to find or make a table widget.  I have looked into making it and will start coding this weekend if it isn't available.

Basically I need a multi-column list with column headers for each row.  The number of columns is know when the table is created.

Share this post


Link to post
Share on other sites

Please post widgets in the "Development and Feedback" section of the forum as a zip or 7z file if the widget may be if use to others. We will then look at including it into the official repository.

If you widget is highly specialised for your application but you want to share the code for others to look at, the appropriate section is the "User Projects" section of the forum.

No table widget currently exists. We would love to have your contribution. 

Share this post


Link to post
Share on other sites

I have a roughed out gwinTable interface definition.  I basically took the gwinList and copied it to gwinTable, left in all of the copyrights, and changed the names.  I changed how the list_head was allocated to use an array of pointers to gfxQueueASync structures.  This will design make it easier to support table cell selection.  I thought of leaving it as a single gfxQueueASync structure and have each element represent a complete row.  This design will make row selection more convenient.  The api is not totally flushed out yet, I figured I would get some feedback before I went too far.

Anyway, I want to build this for more then just me, is there a design review process for widgets?  If the api is not correct, others won't use it and I will have wasted lots of time.  

Share this post


Link to post
Share on other sites

Thank you, we appreciate that you want to make something that can be added to the repository at the end.

Earlier you mentioned that the number of rows and columns is known/fixed. Why would you mess with using queues then? To me it sounds like you should be using a static array instead. That saves a lot of overhead.

If you like you can attach your header file to a post in this topic once you think that it's ready. I can give it a look :)
There are no generic widget design guide lines as there is not much room for customization. The VMT is pretty much gives all the guidelines.

Share this post


Link to post
Share on other sites
47 minutes ago, Joel Bodenmann said:

Earlier you mentioned that the number of rows and columns is known/fixed. Why would you mess with using queues then? To me it sounds like you should be using a static array instead. That saves a lot of overhead.

Only the number of columns are known for the current implementation.  For my project I also know the number of rows, because they are database rows from a select.  If that restriction can be lifted I could use an array.

Share this post


Link to post
Share on other sites

I like the idea of queue items for both rows and columns. This definitely provides the best flexibility for a generic widget. AsyncQueues are very efficient. They only use 4 bytes per item on most platforms.

Share this post


Link to post
Share on other sites

I actually had the idea this morning to build two version:

gwinTable: a row oriented widget that uses less resources, basically each element of the single queue is a row element and contains everything for a complete row.  In this widget cells are not selectable.  In this widget each row can have an image but not each cell.  

gwinGrid: a cell oriented widget that uses a queue for each column and allows cell wise operations, each cell can have an image.  row selection is not an option.

If there is no objection, this is what I will plan.  I can have the header files done by the end of the day.

Share this post


Link to post
Share on other sites

Easy question:  I have the table mostly working but have a question.  The standard seems to be to not draw horizontal lines for the rows of the List object.  Does this mean it is best to not draw the vertical lines for the columns?

If no lines then it seems reasonable to implement

gwinTableSetOddBackground(...); 
and
gwinTableSetEvenBackground(...);

I have already implemented 
gwinTableItemSetBackground(=...);

This allows for changing the background of the rows to make it easier to follow what is happening and doesn't incur the cost of more drawing, since the row has to be drawn anyway.

Also, the entire list is redrawn when a new row is selected, is there a reason I shouldn't optimize this, so only the two rows that changed need to be refreshed?  Or doesn't this make a performance difference?

Share this post


Link to post
Share on other sites

It is all about the design decisions you make when coding the widgets. We strive to give maximum functionality in the smallest possible code and ram.

That sometimes leads to contradictory requirements. Which way you lean is up to you provided it is something you have thought about.

Sometimes we use an option define to control whether extra functionality is included. Another trick we use is to have different display methods as different draw routines. Sometimes it is an init time flag. Eg. The question on gridlines could be either an alternative draw function or a init flag to determine if gridlines should be drawn.

Your question on optimised drawing...

We tend to redraw the whole control. While slower it usually uses less code and doesnt have possible issues relating to redraw timing. The extra redrawing is usually not visible to the end user as you are overwriting without changing the bulk of the widget surface. It is also the more compatible with ugfx3 where we are considering supporting limited clip area redrawing. In that situation all the redrawing code would be called but only clip area would be updated to the screen.

Share this post


Link to post
Share on other sites
5 hours ago, inmarket said:

Your question on optimised drawing...

We tend to redraw the whole control. While slower it usually uses less code and doesnt have possible issues relating to redraw timing. The extra redrawing is usually not visible to the end user as you are overwriting without changing the bulk of the widget surface. It is also the more compatible with ugfx3 where we are considering supporting limited clip area redrawing. In that situation all the redrawing code would be called but only clip area would be updated to the screen.

I copied the List Widget to get a head start on the table widget and the list widget redraws the background and then redraws the text for each row.  If there is a large amount of data the redraw shows every line being redrawn.

Share this post


Link to post
Share on other sites
2 hours ago, Joel Bodenmann said:

What are you trying to say / ask? @inmarket said exactly that.

We tend to redraw the whole control. While slower it usually uses less code and doesnt have possible issues relating to redraw timing. The extra redrawing is usually not visible to the end user as you are overwriting without changing the bulk of the widget surface. 

@inmarket said:
We tend to redraw the whole control. While slower it usually uses less code and doesnt have possible issues 
relating to redraw timing. The extra redrawing is usually not visible to the end user as you are overwriting
without changing the bulk of the widget surface. 

In the case of the List widget and the Table widget The redraw visibly shows every line being redrawn in the simple case of a select. If it isn't a hard rule to not optimize redraw I would like to do it for the table widget.  The reason it is visible is that each line is drawn with the background so the current text is cleared and then with the text is rewritten.  

Share this post


Link to post
Share on other sites

I tried this widget. The function gwinTableSetSelected()  worked  not properly. I fixed this problem.  Sorry for my English.
 

void gwinTableSetSelected(GHandle gh, int row, bool_t doSelect) {
	const gfxQueueASyncItem   *   qi;
	int                     i;

	// is it a valid handle?
	if (gh->vmt != (gwinVMT *)&tableVMT)
		return;

	// watch out for an invalid row
	if (row < 0 || row >= gh2obj->rowCount)
		return;

	// If not a multiselect mode - clear previous selected row
	if (doSelect && !(gh->flags & GTABLE_FLG_MULTISELECT)) {
		for(qi = gfxQueueASyncPeek(&gh2obj->table_head); qi; qi = gfxQueueASyncNext(qi)) {
			if (qi2li->flags & GTABLE_FLG_SELECTED) {
				qi2li->flags &= ~GTABLE_FLG_SELECTED;
				qi2li->modified = GTABLE_TEXT_MODIFIED;
			  gh2obj->modified |= GTABLE_BODY_MODIFIED;
				break;
			}
		}
	}
	// Danger Will Robinson
	// Find row and set selected or not
	for(qi = gfxQueueASyncPeek(&gh2obj->table_head), i = 0; qi; qi = gfxQueueASyncNext(qi), i++) {
		if (i == row) {
			if (!doSelect && (qi2li->flags & GTABLE_FLG_SELECTED) > 0){
				qi2li->flags &= ~GTABLE_FLG_SELECTED;
				qi2li->modified = GTABLE_TEXT_MODIFIED;
				gh2obj->modified |= GTABLE_BODY_MODIFIED;}
    if (doSelect && (qi2li->flags & GTABLE_FLG_SELECTED) == 0){
				qi2li->flags |= GTABLE_FLG_SELECTED;
        qi2li->modified = GTABLE_TEXT_MODIFIED;
        gh2obj->modified |= GTABLE_BODY_MODIFIED;}
			break;


		}
	}
	_gwinUpdate(gh);
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×