flu_file_chooser.cpp
来自「ncbi源码」· C++ 代码 · 共 2,471 行 · 第 1/5 页
CPP
2,471 行
}Flu_File_Chooser :: FileColumns :: FileColumns( int x, int y, int w, int h, Flu_File_Chooser *c ) : Fl_Tile( x, y, w, h ){ chooser = c; W1 = int(float(w)*0.35f); W2 = int(float(w)*0.20f); W3 = int(float(w)*0.15f); W4 = w-W1-W2-W3; Fl_Box *box = new Fl_Box( x+50, y, w-200, h ); add_resizable( *box ); c->detailNameBtn = new Flu_Button( x, y, W1, h, "Name" ); c->detailNameBtn->align( FL_ALIGN_CLIP ); c->detailNameBtn->callback( Flu_File_Chooser::_sortCB, c ); { CBTile *tile = new CBTile( x+W1, y, W2+W3+W4, h, c ); Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-150, tile->h() ); tile->add_resizable( *box ); c->detailTypeBtn = new Flu_Button( x+W1, y, W2, h, "Type" ); c->detailTypeBtn->align( FL_ALIGN_CLIP ); c->detailTypeBtn->callback( Flu_File_Chooser::_sortCB, c ); { CBTile *tile = new CBTile( x+W1+W2, y, W3+W4, h, c ); Fl_Box *box = new Fl_Box( tile->x()+50, tile->y(), tile->w()-100, tile->h() ); tile->add_resizable( *box ); c->detailSizeBtn = new Flu_Button( x+W1+W2, y, W3, h, "Size" ); c->detailSizeBtn->align( FL_ALIGN_CLIP ); c->detailSizeBtn->callback( Flu_File_Chooser::_sortCB, c ); c->detailDateBtn = new Flu_Button( x+W1+W2+W3, y, W4, h, "Date" ); c->detailDateBtn->align( FL_ALIGN_CLIP ); c->detailDateBtn->callback( Flu_File_Chooser::_sortCB, c ); tile->end(); } tile->end(); } end();}Flu_File_Chooser :: FileColumns :: ~FileColumns(){}void Flu_File_Chooser :: FileColumns :: resize( int x, int y, int w, int h ){ // TODO resize the buttons/tiles according to their stored relative sizes Fl_Tile::resize( x, y, w, h );}int Flu_File_Chooser :: FileColumns :: handle( int event ){ if( event == FL_DRAG ) { // the user is probably dragging to resize the columns // update the sizes for each entry chooser->updateEntrySizes(); chooser->redraw(); } return Fl_Tile::handle(event);}void Flu_File_Chooser :: filenameCB(){ filenameEnterCallback = true; cd( filename.value() );}inline bool _isProbablyAPattern( const char *s ){ return( strpbrk( s, "*;|[]?" ) != NULL );}void Flu_File_Chooser :: okCB(){ // only hide if the filename is not blank or the user is choosing directories, // in which case use the current directory //printf( "%s\n", filename.value() ); if( selectionType & DIRECTORY ) {#ifdef WIN32 if( strcmp( filename.value(), "My Computer" ) == 0 ) return;#endif if( !(selectionType & MULTI )) { if( strlen( filename.value() ) != 0 ) cd( filename.value() ); filename.value( currentDir.c_str() ); filename.position( filename.size(), filename.size() ); } hide(); } else { if( strlen( filename.value() ) != 0 ) { if( _isProbablyAPattern( filename.value() ) ) { cd( filename.value() ); return; }#ifdef WIN32 if( filename.value()[1] == ':' )#else if( filename.value()[0] == '/' )#endif if( fl_filename_isdir( filename.value() ) ) { filename.value( "" ); return; } // prepend the path FluSimpleString path = currentDir + filename.value(); filename.value( path.c_str() ); filename.position( filename.size(), filename.size() ); hide(); } }}void Flu_File_Chooser :: homeCB(){#ifdef WIN32 cd( "/" );#else cd( userHome.c_str() );#endif}void Flu_File_Chooser :: desktopCB(){#ifdef WIN32 FluSimpleString s = "/Desktop";#else FluSimpleString s = userHome + "Desktop";#endif cd( s.c_str() );}#define QSCANL( field ) \ while( ((Flu_File_Chooser::Entry*)array[left])->field < \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++#define QSCANR( field ) \ while( ((Flu_File_Chooser::Entry*)array[right])->field > \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) right--#define RQSCANL( field ) \ while( ((Flu_File_Chooser::Entry*)array[left])->field > \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) left++#define RQSCANR( field ) \ while( ((Flu_File_Chooser::Entry*)array[right])->field < \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) right--#define CASE_QSCANL( field ) \ while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++#define CASE_QSCANR( field ) \ while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right--#define CASE_RQSCANL( field ) \ while( casecompare( ((Flu_File_Chooser::Entry*)array[left])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++#define CASE_RQSCANR( field ) \ while( casecompare( ((Flu_File_Chooser::Entry*)array[right])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right--#define CUSTOM_QSCANL( field ) \ while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) left++#define CUSTOM_QSCANR( field ) \ while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) right--#define CUSTOM_RQSCANL( field ) \ while( customSort( ((Flu_File_Chooser::Entry*)array[left])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) > 0 ) left++#define CUSTOM_RQSCANR( field ) \ while( customSort( ((Flu_File_Chooser::Entry*)array[right])->field, \ ((Flu_File_Chooser::Entry*)array[pivot])->field ) < 0 ) right--void Flu_File_Chooser :: _qSort( int how, bool caseSort, Fl_Widget **array, int low, int high ){ int left, right, pivot; Fl_Widget *temp; bool reverse = ( how & SORT_REVERSE ); if( high > low ) { left = low; right = high; pivot = low; while( right >= left ) { switch( how & ~SORT_REVERSE ) { case SORT_NAME: if( reverse ) { if( customSort ) { CUSTOM_RQSCANL( filename.c_str() ); CUSTOM_RQSCANR( filename.c_str() ); } else if( !caseSort ) { CASE_RQSCANL( filename ); CASE_RQSCANR( filename ); } else { RQSCANL( filename ); RQSCANR( filename ); } } else { if( customSort ) { CUSTOM_QSCANL( filename.c_str() ); CUSTOM_QSCANR( filename.c_str() ); } else if( !caseSort ) { CASE_QSCANL( filename ); CASE_QSCANR( filename ); } else { QSCANL( filename ); QSCANR( filename ); } } break; case SORT_SIZE: if( reverse ) { RQSCANL( isize ); RQSCANR( isize ); } else { QSCANL( isize ); QSCANR( isize ); } break; case SORT_DATE: if( reverse ) { RQSCANL( idate ); RQSCANR( idate ); } else { QSCANL( idate ); QSCANR( idate ); } break; case SORT_TYPE: if( reverse ) { RQSCANL( description ); RQSCANR( description ); } else { QSCANL( description ); QSCANR( description ); } break; } if( left > right ) break; temp = array[left]; array[left] = array[right]; array[right] = temp; left++; right--; } _qSort( how, caseSort, array, low, right ); _qSort( how, caseSort, array, left, high ); }}Flu_File_Chooser :: FileList :: FileList( int x, int y, int w, int h, Flu_File_Chooser *c ) : Flu_Wrap_Group( x, y, w, h ){ chooser = c;}Flu_File_Chooser :: FileList :: ~FileList(){}void Flu_File_Chooser :: FileList :: sort( int n ){ if( n != -1 ) numDirs = n; if( children() == 0 ) return; // the directories are already first. sort the directories then the names lexigraphically //if( chooser->sortMethod & Flu_File_Chooser::SORT_NAME ) Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 ); Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 ); chooser->redraw();}int Flu_File_Chooser :: FileList :: handle( int event ){ //printf( "%d\n", event ); if( event == FL_FOCUS || event == FL_UNFOCUS ) return 1; if( Flu_Wrap_Group::handle( event ) ) return 1; // if push on no file, unselect all files and turn off editing mode if( event == FL_PUSH && !Fl::event_key( FL_SHIFT ) && !Fl::event_key( FL_CTRL ) ) { chooser->unselect_all(); chooser->filename.value( "" ); chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); if( Fl::event_button3() ) return chooser->popupContextMenu( NULL ); return 1; } else if( event == FL_KEYDOWN ) { if( Fl::event_key( FL_Delete ) ) { // recycle by default, unless the shift key is held down chooser->trashCB( !Fl::event_state( FL_SHIFT ) ); return 1; } Flu_File_Chooser::Entry *e = chooser->lastSelected; if( !e ) { for( int i = 0; i < children(); i++ ) if( ((Flu_File_Chooser::Entry*)child(i))->selected ) { e = (Flu_File_Chooser::Entry*)child(i); break; } } if( e ) { switch( Fl::event_key() ) { case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e ); if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break; case FL_Down: e = (Flu_File_Chooser::Entry*)next( e ); if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; case FL_Left: e = (Flu_File_Chooser::Entry*)left( e ); break; case FL_Right: e = (Flu_File_Chooser::Entry*)right( e ); break; case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break; case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; case FL_Enter: chooser->filenameEnterCallback = true; chooser->cd( e->filename.c_str() ); return 1; case ' ': chooser->cd( e->filename.c_str() ); return 1; default: e = 0; break; } if( e ) { chooser->unselect_all(); e->selected = true; chooser->lastSelected = e; chooser->filename.value( e->filename.c_str() ); chooser->filename.position( chooser->filename.size(), chooser->filename.size() ); chooser->redraw(); scroll_to( e ); //take_focus(); return 1; } } } return 0;}Flu_File_Chooser :: FileDetails :: FileDetails( int x, int y, int w, int h, Flu_File_Chooser *c ) : Fl_Pack( x, y, w, h ){ chooser = c;}Flu_File_Chooser :: FileDetails :: ~FileDetails(){}void Flu_File_Chooser :: FileDetails :: scroll_to( Fl_Widget *w ){ // we know all the widgets are the same height // so just find this widget and scroll to the accumulated height int H = 0; for( int i = 0; i < children(); i++ ) { if( child(i) == w ) { if( H > (int)chooser->filescroll->scrollbar.maximum() ) H = (int)chooser->filescroll->scrollbar.maximum(); chooser->filescroll->position( 0, H ); return; } H += w->h(); }}void Flu_File_Chooser :: FileDetails :: sort( int n ){ if( n != -1 ) numDirs = n; if( children() == 0 ) return; // the directories are already first. sort the directories then the names lexigraphically //if( chooser->sortMethod & Flu_File_Chooser::SORT_NAME ) Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), 0, numDirs-1 ); Flu_File_Chooser::_qSort( chooser->sortMethod, chooser->caseSort, (Fl_Widget**)array(), numDirs, children()-1 ); chooser->redraw();}Fl_Widget* Flu_File_Chooser :: FileDetails :: next( Fl_Widget* w ){ for( int i = 0; i < children()-1; i++ ) { if( w == child(i) ) return child(i+1); } return NULL;}Fl_Widget* Flu_File_Chooser :: FileDetails :: previous( Fl_Widget* w ){ for( int i = 1; i < children(); i++ ) { if( w == child(i) ) return child(i-1); } return NULL;}int Flu_File_Chooser :: FileDetails :: handle( int event ){ if( event == FL_FOCUS || event == FL_UNFOCUS ) return 1; if( Fl_Pack::handle( event ) ) return 1; else if( event == FL_PUSH ) return 1; else if( event == FL_KEYDOWN ) { if( Fl::event_key( FL_Delete ) ) { // recycle by default, unless the shift key is held down chooser->trashCB( !Fl::event_state( FL_SHIFT ) ); return 1; } Flu_File_Chooser::Entry *e = chooser->lastSelected; if( !e ) { for( int i = 0; i < children(); i++ ) if( ((Flu_File_Chooser::Entry*)child(i))->selected ) { e = (Flu_File_Chooser::Entry*)child(i); break; } } if( e ) { switch( Fl::event_key() ) { case FL_Up: e = (Flu_File_Chooser::Entry*)previous( e ); if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(0); break; case FL_Down: e = (Flu_File_Chooser::Entry*)next( e ); if( !e && children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; case FL_Home: if( children() ) e = (Flu_File_Chooser::Entry*)child(0); break; case FL_End: if( children() ) e = (Flu_File_Chooser::Entry*)child(children()-1); break; case FL_Enter: chooser->filenameEnterCallback = true; chooser->cd( e->filename.c_str() ); return 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?