libglui / glui

GLUI is a GLUT-based C++ user interface library which provides controls such as buttons, checkboxes, radio buttons, and spinners to OpenGL applications. It is window-system independent, using GLUT or FreeGLUT.
Other
194 stars 82 forks source link

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

Open djwebb opened 5 years ago

djwebb commented 5 years ago

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.

nigels-com commented 5 years ago

Two initial thoughts:

djwebb commented 5 years ago

Nigel,

Sorry - I am not an expert on this:

  • Use std::list<>, perhaps I am happy to make the change but what do I need to do?

  • do all the whitespace cleanup seperately for clarity I tend to modify whitespace as I go along - to make it easier for myself to follow the code. Is there a way I can use git to revert just the whitespace?

Regards,

David.

nigels-com commented 5 years ago

@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 commented 5 years ago

On Thursday, 14 March 2019 11:19:15 GMT Nigel Stewart wrote:

@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?

Bit behind today. I'll try and get it checked over the weekend.

David.

nigels-com commented 5 years ago

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 commented 5 years ago

On Thursday, 14 March 2019 11:19:15 GMT Nigel Stewart wrote:

@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?

I tool a new clone, checked out remotes/origin/qsort and compiled. The compiler complained (see below) but otherwise compiled the glui library and examples without problems.

I then compiled and tried my own main program with the FileBrowser routine.
Everything worked correctly.

Anyway - as far as I can tell the changes to glui are fully functional.
Please let me know once they are on the master branch.

Thanks,

David.

djwebb commented 5 years ago

I forgot the compiler complaints:

   quaternion.cpp: In function ‘quat operator*(const quat&, const quat&)’:
   quaternion.cpp:117:55: warning: suggest parentheses around arithmetic
                  in operand of ‘^’ [-Wparentheses]
   return quat( a.s*b.s - a.v*b.v, a.s*b.v + b.s*a.v + a.v^b.v );

   glui_textbox.cpp:964:3: note: in expansion of macro ‘CLAMP’
   CLAMP( insertion_pt, 0, text.length()); /* Make sure insertion_pt
   ^~~~~
   glui_internal.h:104:66: warning: comparison between signed and unsigned  
                integer expressions [-Wsign-compare]
   #define CLAMP(x,lo,hi)  {if ((x) < (lo)) {(x)=(lo);} else if((x) >
                                                    (hi)) {(x)=(hi);}}

 Similar CLAMP errors at lines 966 and 968.

David

m-7761 commented 5 years ago

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 commented 5 years ago

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);
}