/* fieldlistview.h * This file belongs to Worker, a file manager for UN*X/X11. * Copyright (C) 2002-2019 Ralf Hoffmann. * You can contact me at: ralf@boomerangsworld.de * or http://www.boomerangsworld.de/worker * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NEWLISTVIEW_H #define NEWLISTVIEW_H #include "aguixdefs.h" #include "util.h" #include "guielement.h" #include "fieldlvrowdata.h" #include #include #include #include #include #include class AGUIX; class AGUIXFont; class FieldListView:public GUIElement { public: FieldListView( AGUIX *caguix, int cx, int cy, int cwidth, int cheight, int cdata ); virtual ~FieldListView(); FieldListView( const FieldListView &other ); FieldListView &operator=( const FieldListView &other ); void setNrOfFields( int nv ); int getNrOfFields() const; void setText( int row, int field, std::string text, bool update_simple_set = false ); std::string getText( int row, int field ) const; void trimElements(); void setFieldWidth( int field, int width ); void setFieldWidthQ( int field, int width ); void setSize( int rows ); // create/delete needed rows int getUsedWidth( int field ); int addRow(); int deleteRow( int row ); int insertRow( int row ); void swapRows( int row1, int row2 ); void setStrikeOut( int row, int field, bool nv ); bool getStrikeOut( int row, int field ) const; void setStrikeOutStart( int row, int field, size_t nv ); size_t getStrikeOutStart( int row, int field ) const; void setXOffset( int nv, bool no_redraw = false ); int getMaxTextWidth(); void setYOffset( int nv, bool no_redraw = false ); typedef enum { ALIGN_LEFT, ALIGN_RIGHT } align_t; void setFieldAlign( int field, align_t nv ); void setFieldAlignQ( int field, align_t nv ); void setFieldTextQ( int field, const std::string nv ); void setFieldText( int field, const std::string nv ); std::string getFieldText( int field ) const; // true to merge with following field text void setFieldTextMergedQ( int field, bool nv ); void setFieldTextMerged( int field, bool nv ); void setFieldTextResizeable( int field, bool nv ); virtual void redraw(); void redraw( int element ); typedef enum { CC_NORMAL = 0, CC_SELECT = 1, CC_ACTIVE = 2, CC_SELACT = 3 } colorclass_t; void setFG( int row, colorclass_t cc, int col ); int getFG( int row, colorclass_t cc ) const; void setBG( int row, colorclass_t cc, int col ); int getBG( int row, colorclass_t cc ) const; void setSelect( int row, bool nv ); void setSelectQ( int row, bool nv ); bool getSelect( int row ) const; void setActiveRow( int nv ); void setActiveRowQ( int nv ); int getActiveRow() const; void setVisMark( int row, bool nv ); void setVisMarkQ( int row, bool nv ); bool getVisMark( int row ) const; virtual void resize( int w, int h ); int getData() const; void setData( int ); virtual void flush(); virtual bool handleMessage( XEvent *E, Message *msg ); int getXOffset() const; int getYOffset() const; int getElements() const; int getMaxDisplayV() const; void setHBarState( int state ); void setVBarState( int state ); int getHBarState() const; int getVBarState() const; void setVBarWidth( int new_width ); int getVBarWidth() const; void setHBarHeight( int new_height ); int getHBarHeight() const; void scrollV( int delta, bool no_redraw = false ); void scrollV1( int dir, bool no_redraw = false ); void setSelectHandler( void (*nsh)( FieldListView*, int element ) ); void setSelectHandler( std::function< void( FieldListView*, int element ) > cb ); void showActive(); void centerActive(); int setFont ( const char * ); virtual const char *getType() const; virtual bool isType( const char *type ) const; virtual bool isParent( Window ) const; int getRowHeight() const; int getMBG() const; void setMBG( int color ); int maximizeX(); int getMaximumWidth(); int maximizeY(); int getMaximumHeight(); void showRow( int row, bool redraw = true); void setData( int row, int ndata ); int getData( int row, int fallback_value ) const; void setDataExt( int row, FieldLVRowData *ndata ); FieldLVRowData *getDataExt( int row ) const; bool isValidRow( int row ) const; typedef enum { PRECOLOR_NONE, PRECOLOR_NORMAL, PRECOLOR_ONLYSELECT, PRECOLOR_ONLYACTIVE, PRECOLOR_NOTSELORACT } precolor_t; void setPreColors( int row, precolor_t mode ); void setDisplayFocus( bool nv ); bool getDisplayFocus() const; void cond_redraw(); bool isRowVisible( int row ) const; void setShowHeader( bool nv ); bool getShowHeader() const; int getHeaderHeight() const; void redrawHeader(); void setHeaderFG( int col ); void setHeaderBG( int col ); int getHeaderFG() const; int getHeaderBG() const; int getHScrollStep() const; int getFieldWidth( int field ) const; int getEffectiveFieldWidth( int field ); typedef enum { SELECT_BUTTON, ACTIVATE_BUTTON, SCROLL_BUTTON, ENTRY_PRESSED_MSG_BUTTON } buttonfunction_t; static int changeButtonFunction( buttonfunction_t bf, int button, int mod = 0 ); typedef enum { MOUSE_SELECT_NORMAL, MOUSE_SELECT_ALT } mouse_select_t; static int changeSelectMode( mouse_select_t nm ); class ColorDef { public: ColorDef(); ~ColorDef(); void setFG( colorclass_t cc, int col ); int getFG( colorclass_t cc ) const; void setBG( colorclass_t cc, int col ); int getBG( colorclass_t cc ) const; private: int fg[4], bg[4]; }; void setColor( int row, const ColorDef &col ); ColorDef getColor( int row ) const; void simpleRedrawUpdatedRows(); void timeLimitedRedraw(); void setGlobalFieldSpace( int spacing ); int getFieldSpace( int field ) const; void setFieldSpace( int field, int spacing ); void setHighlightSegments( int row, int field, const std::vector< size_t > &segments ); const std::vector< size_t > *getHighlightSegments( int row, int field ) const; void clearHighlightSegments(); void setConsiderHeaderWidthForDynamicWidth( bool nv ); bool getConsiderHeaderWidthForDynamicWidth() const; void setDefaultColorMode( precolor_t mode ); struct on_demand_data { on_demand_data() : done( false ), text_set( false ), segments_set( false ), strike_out_set( false ) {} bool done; // indicates that the caller is done with ondemand data std::string text; // the text for the given row x column bool text_set; std::vector< size_t > segments; // highlight segments bool segments_set; bool strike_out; bool strike_out_set; size_t strike_out_start = 0; bool strike_out_start_set = false; }; void setOnDemandCallback( std::function< void( FieldListView*, int row, int field, struct on_demand_data &data ) > cb ); void clearOnDemandDataAvailableFlag(); void clearOnDemandDataAvailableFlag( int row ); typedef enum { HEADER_SORT_HINT_NONE, HEADER_SORT_HINT_UP, HEADER_SORT_HINT_DOWN } header_sort_hint_t; void setSortHint( int field, header_sort_hint_t hint ); void unsetSortHint(); int getRowYPosition( int row ); void setShowSelectionInVBar( bool nv ); protected: int fields; int *fieldwidth; int *used_width; int *maxrow; align_t *fieldalign; std::string *fieldtext; bool *fieldtextmerged; bool *fieldtextResizeable; std::vector< int > m_header_text_width; std::vector< int > m_field_spacing; int fieldtextclicked; class Content { public: Content(); ~Content(); Content( const Content &other ); Content &operator=( const Content &other ); void setText( int field, std::string text ); void trim( int newfields ); std::string getText( int field ) const; void setFG( colorclass_t cc, int col ); int getFG( colorclass_t cc ) const; void setBG( colorclass_t cc, int col ); int getBG( colorclass_t cc ) const; void setSelect( bool nv ); bool getSelect() const; void setDataExt( FieldLVRowData *ndata ); FieldLVRowData *getDataExt() const; void setData( int ndata ); int getData() const; void setMark( bool nv ); bool getMark() const; void setStrikeOut( int field, bool nv ); bool getStrikeOut( int field ) const; void setStrikeOutStart( int field, size_t nv ); size_t getStrikeOutStart( int field ) const; void setHighlightSegments( int field, const std::vector< size_t > &segments ); const std::vector< size_t > *getHighlightSegments( int field ) const; void clearHighlightSegments(); bool getOnDemandDataAvailable() const { return m_ondemand_data_available; } void setOnDemandDataAvailable( bool nv ) { m_ondemand_data_available = nv; } protected: int cur_fields; std::string **texts; std::vector< bool > m_strike_out; std::vector< size_t > m_strike_out_start; std::vector< std::vector< size_t > > *m_highlight_segments; int fg[4], bg[4]; bool select; int data; FieldLVRowData *dataExt; bool mark; bool m_ondemand_data_available; }; Content **elementarray; int arraysize; int elements; void increaseArray( int newsize ); void checkShrink(); int xoffset, yoffset, maxdisplayv; void redrawContent(); void redrawLine( int element ); int activerow; int data; static const char *type; int hbar; int hbar_height; int hbar_dir; bool hbar_pressed; int vbar; int vbar_width; int vbar_dir; bool vbar_pressed; void mredraw(); void hbarredraw(); void vbarredraw(); Window hbarwin,vbarwin; void clearNonElements(); void handleExpose( Window msgwin, int ex, int ey, int ew, int eh ); virtual void handleSelect( Message *msg ); virtual void handleMiddle( Message *msg ); void handleThird( Message *msg ); void handleHBar( Message *msg ); void handleVBar( Message *msg ); bool handleKeys( Message *msg ); void handleHeader( Message *msg ); void handleEntryPressed( Message *msg ); void (*selecthandler)( FieldListView*,int element ); std::function< void( FieldListView*, int element ) > m_select_handler; void setupBars(); virtual void runSelectHandler( int element ); void recalcMaxValues(); int getHeaderTextWidth( int field ); AGUIXFont *font; struct timeval lastwheel; int mbg; int elementHeight, elementWidth, ox, oy; void resetWin( bool doRedraw ); int getRowForMouseY( int my ) const; Pixmap buffer; void drawBuffer(); void drawBuffer( int dx, int dy, int dw, int dh ); void drawBuffer( int element ); bool displayFocus; int getInnerWidth() const; int getInnerHeight() const; virtual void doCreateStuff(); virtual void doDestroyStuff(); void sendScrollEvent( int type ); bool cond_changed; bool showHeader; int headerCols[2]; int getFieldForPoint( int mx, int my, int *start_x = NULL, int *end_x = NULL ); typedef enum { VBAR_IDLE, VBAR_SCROLL, VBAR_SCROLL_UP, VBAR_SCROLL_DOWN } vbarMode_t; vbarMode_t vbarMode; int grabs; int scrollDelta; typedef enum { HBAR_IDLE, HBAR_SCROLL, HBAR_SCROLL_LEFT, HBAR_SCROLL_RIGHT } hbarMode_t; hbarMode_t hbarMode; typedef enum { THIRD_IDLE, THIRD_SCROLL } thirdMode_t; thirdMode_t thirdMode; int scrollXDir, scrollYDir; void updateScrollValues( int mx, int my ); int selectRowsRange( int startRow, int endRow, bool state ); int singleSelectRow( int row, bool state ); typedef enum { SELECT_IDLE, SELECT_HOLD, SELECT_SCROLL_UP, SELECT_SCROLL_DOWN, SELECT_IGNORE } selectMode_t; selectMode_t selectMode; int clickLastSelectedRow, clickFirstSelectedRow; bool clickState; int clickSelected; typedef enum { MIDDLE_IDLE, MIDDLE_HOLD, MIDDLE_SCROLL_UP, MIDDLE_SCROLL_DOWN, MIDDLE_IGNORE } middleMode_t; middleMode_t middleMode; int _last_single_select_row; Time _last_single_select_time; int _last_single_middle_row; Time _last_single_middle_time; typedef enum { HEADER_IDLE, HEADER_CLICK, HEADER_DRAG } headerMode_t; headerMode_t headerMode; void selectModeIgnore(); void middleModeIgnore(); void prepareBG( bool force = false ); Pixmap _header_pixmap; int _header_pixmap_w, _header_pixmap_h; void freeHeaderPixmap(); int checkHeaderPixmap( int pw, int ph ); int getBorderWidth() const; int drag_base_x; int drag_base_w; Time last_drag_time; int last_drag_clicked; int drag_field; bool header_cursor_set; // true if cursor for header dragging is set int findPreviousRealField( int f ); int getLastField( int *start_x, int *end_x ); int findResizeableField( int f ); static unsigned int _select_button, _select_buttonmask; static unsigned int _activate_button, _activate_buttonmask, _activate_mod; static unsigned int _scroll_button, _scroll_buttonmask, _scroll_mod; static unsigned int _entry_pressed_msg_button, _entry_pressed_msg_buttonmask, _entry_pressed_msg_mod; static mouse_select_t _select_mode; unsigned int getCurrentMouseButtonState( Window twin ); bool checkForValidButtonMod( unsigned int button, unsigned int keystate, unsigned int matching_mod ); void initStaticDefaultColors(); std::set m_updated_rows; bool m_complete_update; struct timeval m_last_update_time; int m_global_field_spacing; bool m_consider_header_for_dynamic_width; precolor_t m_default_color_mode; static ColorDef s_default_element_colors; std::function< void( FieldListView*, int row, int field, struct on_demand_data &data ) > m_ondemand_callback; void updateOnDemandData(); struct header_sort_hint { header_sort_hint() : field( -1 ), hint( HEADER_SORT_HINT_NONE ) {} int field; header_sort_hint_t hint; } sort_hint; Pixmap m_vbar_selectbuffer = 0; int m_vbar_selectbuffer_w = -1; int m_vbar_selectbuffer_h = -1; std::vector< bool > m_vbar_select_dirty; std::vector< int > m_vbar_select_count; bool m_vbar_select_some_dirty = false; bool m_show_selection_in_vbar = false; bool m_vbar_rebuild_required = false; void drawSelectStateVBar(); void freeVBarSelectBuffer(); int checkVBarSelectBuffer( int tw, int th ); void updateSelectState( int element, bool only_selected ); }; #endif