Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code to order directories and files in filebrowser using qsort #89

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

djwebb
Copy link

@djwebb djwebb commented Nov 17, 2018

The code was originally written for the previous version of glui. I have modified it to work with your latest version. The main changes are in files glui_filebrowser.cpp and include/GL/glui.h, but I have made a few other small changes to get rid of compiler warnings (unused variables, comparison of signed and unsigned int, etc.)

I have left a lot of debug print statements, these are turned off but you can switch them on (iprint=1). The unused variablee lines have been commented out but are still there.

If you want a version without the debug statements or the commented out lines let me know.

Regards,

David.

David Webb added 5 commits June 8, 2018 12:07
==================================

Add list processing functions to glui_filebrowser.cpp and
glui.h to allow Filebrowser to process directory entries.
============================

Changes to glui_filebrowser.cpp and glui_list.cpp to correct bug.
=========================================

The FileBrowser now sorts the file and directory names.  There
is also an option to filter the filenames.  This version still
contains many debug 'printf' statements.

1.  glui.h

    New FileBrowser private variable 'list_filter' and public
    functions 'set filter' and 'filter_cstr' to set and read
    'list filter'.

2.  glui_filebrowser

    C function 'fnmatch' used to filter list of filenames using
    string 'list_filter'.  See:
    http://pubs.opengroup.org/onlinepubs/009695399/functions/fnmatch.html

    C function 'qsort' used to sort filenames and directory names
    using criteria of new private function 'fb_list_compare'.
    If present this places './' first, '../' next followed by
    directories in order and then filtered files in order.

3.  example6.cpp

    New variable 'fb_filter', plus EditText box to process
    filter.  Callback 'filter_cb' sets 'list_filter' and
    calls 'fbreaddir' to reprocess directory.
Merge djw_1 with origin/master to ensure there are no new conflicts.
A number of small changes made as a result of compiler suggestions.
These include:
   Remove unused variables.
   Comparison of singed and unsigned integers.
   Convert parameters for %p format to (void*).
@nigels-com
Copy link
Collaborator

Two initial thoughts:

  • Use std::list<>, perhaps
  • do all the whitespace cleanup seperately for clarity

@djwebb
Copy link
Author

djwebb commented Mar 14, 2019 via email

@nigels-com
Copy link
Collaborator

@djwebb I managed to rebase this branch with respect to a seperate one that trimmed all the whitespace for the files of interest here. https://github.com/nigels-com/glui/tree/qsort

Would you mind giving it a try to confirm that it's fully functional?

@djwebb
Copy link
Author

djwebb commented Mar 14, 2019 via email

@nigels-com
Copy link
Collaborator

nigels-com commented Mar 14, 2019

My rebase wasn't quite right, but I pushed a fix. Fingers crossed.

(Update: Build seems happy now, at least for Linux: https://travis-ci.org/nigels-com/glui/builds/506232858)

@djwebb
Copy link
Author

djwebb commented Mar 16, 2019 via email

@djwebb
Copy link
Author

djwebb commented Mar 16, 2019 via email

@m-7761
Copy link

m-7761 commented Apr 2, 2019

I will implement something like this. The correct way (other than a kind of linked bubble-sort) is to implement something like glui_format_str that takes the first Item node and unpacks the list into a buffer on the stack, expanding it if truly large, and then relinks it according to a provided predicate.

I've changed add_item so it can work with nodes derived from the item object, so a list is immensely more useful.

EDITED: Or better, takes a generic node, and only the predicate knows it is an Item node. IOW, the predicate can be used with other kinds of Nodes also.

@m-7761
Copy link

m-7761 commented Apr 3, 2019

Follow-up: Oops, sorry, I had it in my head this was just about implementing the missing sort_items (GLUI_Listbox) more or less. There is a lot more code involved here than I expected. I'm wondering if std::sort is not applicable.

Here is some (untested) code I just through together to do a sort. The sorting predicate is unspecified, but could be alphabetical, or give priority to directories. It's based on the buffering strategy of glui_format_str. I wish the Standard Library containers were initially sizeable this way. (Every container I've developed for the COLLADA-DOM library I'm developing is so.)

void glui_sort_siblings(Node &parent, bool(*pred)(Node*,Node*))
{
	enum{ ISIZE=32 };
	Node *stackbuf[ISIZE];
	size_t bufsz = ISIZE;
	Node **buf = stackbuf;

	size_t i = 0; 
	Node *p = parent.first_child();
	for(;;)
	{
		for(;i<bufsz&&p;p=p->next())
		{
			buf[i++] = p;
		}		
		if(!p) break;

		// else make a bigger buf, try again
		bufsz*=2; if(buf==stackbuf) 
		{
			buf = (Node**)malloc(sizeof(Node*)*bufsz);
		}
		else buf = (Node**)realloc(buf,sizeof(Node*)*bufsz);
	}

	std::sort(buf,buf+i,pred);

	if(i>1)
	{
		parent.first_child = buf[0];
		parent.last_child = buf[--i];
		for(i-->0)
		{
			buf[i]->next = buf[i+1];
			buf[i+1]->prev = buf[i];
		}
	}

	if(buf!=stackbuf) free(buf);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants