diff options
Diffstat (limited to 'iup/srccontrols/matrix/iupmat_scroll.c')
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_scroll.c | 282 |
1 files changed, 120 insertions, 162 deletions
diff --git a/iup/srccontrols/matrix/iupmat_scroll.c b/iup/srccontrols/matrix/iupmat_scroll.c index 24bbef2..845d248 100755 --- a/iup/srccontrols/matrix/iupmat_scroll.c +++ b/iup/srccontrols/matrix/iupmat_scroll.c @@ -32,54 +32,32 @@ /* Private functions */ /**************************************************************************/ - -static int iMatrixScrollIsFullVisibleLast(ImatLinColData *p) -{ - int i, sum = 0; - - for(i = p->first; i <= p->last; i++) - sum += p->sizes[i]; - - if (sum > p->visible_size) - return 0; - else - return 1; -} - -/* Scroll columns/lines in the left/top side of the matriz until the last column/line is FULLY visible. - -> m : Define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -static void iMatrixScrollToVisible(Ihandle* ih, int m, int index) +static void iMatrixScrollToVisible(ImatLinColData* p, int index) { - ImatLinColData* p; + /* The work here is just to position first and first_offset, + so "index" is between "first" and "last". */ + + /* It is called only for discrete scrolling, + so first_offset usually will be set to 0. */ + + /* already visible, change nothing */ + if (index > p->first && index < p->last) + return; - if (m == IMAT_PROCESS_LIN) - p = &(ih->data->lines); - else - p = &(ih->data->columns); + /* scroll to visible, means position the cell so the start at left is visible */ - if (index < p->first) + if (index <= p->first) { p->first = index; + p->first_offset = 0; return; } - else if (index > p->last) + else /* (index >= p->last) */ { - /* Increment the first column/line until the index is visible */ - while(index > p->last && p->last != (p->num - 1)) - { - p->first++; - iupMatrixAuxUpdateLast(p); - } - } + p->last = index; - if (index == p->last) - { - /* must increment util the last is fully visible */ - while(index == p->last && p->last != (p->num - 1) && !iMatrixScrollIsFullVisibleLast(p)) - { - p->first++; - iupMatrixAuxUpdateLast(p); - } + /* adjust "first" according to "last" */ + iupMatrixAuxAdjustFirstFromLast(p); } } @@ -133,119 +111,114 @@ static int iMatrixScrollGetPrevNonEmpty(Ihandle* ih, int m, int index) return index; } -static void iMatrixScrollSetFocusScrollToVisible(Ihandle* ih, int m, int index) +static void iMatrixScrollSetFocusScrollToVisible(Ihandle* ih, int lin, int col) +{ + /* moving focus and eventually scrolling */ + iupMatrixFocusSet(ih, lin, col); + + /* set for both because focus maybe hidden */ + iMatrixScrollToVisible(&ih->data->columns, ih->data->columns.focus_cell); + iMatrixScrollToVisible(&ih->data->lines, ih->data->lines.focus_cell); +} + +static void iMatrixScrollSetFocusScrollToVisibleLinCol(Ihandle* ih, int m, int index) { if (m == IMAT_PROCESS_COL) - iupMatrixFocusSet(ih, ih->data->lines.focus_cell, index); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.focus_cell, index); else - iupMatrixFocusSet(ih, index, ih->data->columns.focus_cell); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, index, ih->data->columns.focus_cell); } + /**************************************************************************/ /* Exported functions */ /**************************************************************************/ -/* Move using the cells of matrix. - Receive as a parameter a pointer to a function that will make the work, - in fact. This is done to avoid a test to each of the manipulation cursor - functions, verifying if it is necessary to call or not the scroll - callback. This is only done here. - -> func - pointer to the function that will make the movement - -> mode - parameter passed to func, specify if the movement request is of - the scrollbar or the keyboard - -> pos - parameter passed to func, that will be the handle position function - of the scrollbar, returning the scrollbar thumb position... - if func is other function, this parameter will be ignored - -> m - parameter passed to func, specify which is the mode of operation: - lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] -*/ -void iupMatrixScrollMoveCursor(iupMatrixScrollMoveF func, Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col) { int old_lines_first = ih->data->lines.first; int old_columns_first = ih->data->columns.first; + int old_lines_first_offset = ih->data->lines.first_offset; + int old_columns_first_offset = ih->data->columns.first_offset; - iupMatrixEditForceHidden(ih); + iMatrixScrollToVisible(&ih->data->columns, col); + iMatrixScrollToVisible(&ih->data->lines, lin); - func(ih, mode, pos, m); - - if (ih->data->lines.first != old_lines_first || ih->data->columns.first != old_columns_first) + if ((ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) || + (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset)) { - if (ih->data->columns.first != old_columns_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); + /* when "first" is changed must update scroll pos */ + if (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); - if (ih->data->lines.first != old_lines_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + if (ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN); iMatrixScrollCallScrollTopCb(ih); - iupMatrixDraw(ih, 0); + iupMatrixDraw(ih, 1); } } -void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col) +void iupMatrixScrollMove(iupMatrixScrollMoveFunc func, Ihandle* ih, int mode, float pos, int m) { int old_lines_first = ih->data->lines.first; int old_columns_first = ih->data->columns.first; + int old_lines_first_offset = ih->data->lines.first_offset; + int old_columns_first_offset = ih->data->columns.first_offset; - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, col); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, lin); + iupMatrixEditForceHidden(ih); - if (ih->data->lines.first != old_lines_first || ih->data->columns.first != old_columns_first) + func(ih, mode, pos, m); + + if ((ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) || + (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset)) { - if (ih->data->columns.first != old_columns_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); + /* when "first" is changed must update scroll pos */ + if (ih->data->columns.first != old_columns_first || ih->data->columns.first_offset != old_columns_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); - if (ih->data->lines.first != old_lines_first) - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + if (ih->data->lines.first != old_lines_first || ih->data->lines.first_offset != old_lines_first_offset) + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN); iMatrixScrollCallScrollTopCb(ih); - iupMatrixDraw(ih, 1); + iupMatrixDraw(ih, 0); } } +/************************************************************************************/ + /* This function is called when the "home" key is pressed. In the first time, go to the beginning of the line. In the second time, go to the beginning of the page. In the third time, go to the beginning of the matrix. -> mode and pos : DO NOT USED. */ -void iupMatrixScrollHome(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollHomeFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { (void)unused_m; (void)unused_mode; (void)unused_pos; /* called only for mode==IMAT_SCROLLKEY */ + /* moving focus and eventually scrolling */ if(ih->data->homekeycount == 0) /* go to the beginning of the line */ { - ih->data->columns.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); - iMatrixScrollSetFocusScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.first); + int col = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, IMAT_PROCESS_COL, col); } else if(ih->data->homekeycount == 1) /* go to the beginning of the visible page */ { - iupMatrixFocusSet(ih, ih->data->lines.first, ih->data->columns.first); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.first, ih->data->columns.first); } else if(ih->data->homekeycount == 2) /* go to the beginning of the matrix 1:1 */ { - ih->data->columns.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); - ih->data->lines.first = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_LIN, 1); - - iupMatrixFocusSet(ih, ih->data->lines.first, ih->data->columns.first); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + int lin = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_LIN, 1); + int col = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, 1); + iMatrixScrollSetFocusScrollToVisible(ih, lin, col); } } @@ -255,37 +228,29 @@ void iupMatrixScrollHome(Ihandle* ih, int unused_mode, float unused_pos, int unu In the third time, go to the end of the matrix. -> mode and pos : DO NOT USED. */ -void iupMatrixScrollEnd(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollEndFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { (void)unused_m; (void)unused_mode; (void)unused_pos; /* called only for mode==IMAT_SCROLLKEY */ + /* moving focus and eventually scrolling */ if(ih->data->endkeycount == 0) /* go to the end of the line */ { - int last_col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); - iMatrixScrollSetFocusScrollToVisible(ih, IMAT_PROCESS_COL, last_col); + int col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, IMAT_PROCESS_COL, col); } else if(ih->data->endkeycount == 1) /* go to the end of the visible page */ { - iupMatrixFocusSet(ih, ih->data->lines.last, ih->data->columns.last); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + iMatrixScrollSetFocusScrollToVisible(ih, ih->data->lines.last, ih->data->columns.last); } else if(ih->data->endkeycount == 2) /* go to the end of the matrix */ { - int last_col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); - int last_lin = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_LIN, ih->data->lines.num-1); - - iupMatrixFocusSet(ih, last_lin, last_col); - - /* set for both because current focus maybe hidden */ - iMatrixScrollToVisible(ih, IMAT_PROCESS_COL, ih->data->columns.focus_cell); - iMatrixScrollToVisible(ih, IMAT_PROCESS_LIN, ih->data->lines.focus_cell); + int lin = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_LIN, ih->data->lines.num-1); + int col = iMatrixScrollGetPrevNonEmpty(ih, IMAT_PROCESS_COL, ih->data->columns.num-1); + iMatrixScrollSetFocusScrollToVisible(ih, lin, col); } } @@ -295,7 +260,7 @@ void iupMatrixScrollEnd(Ihandle* ih, int unused_mode, float unused_pos, int unus -> pos : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollLeftUpFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -307,12 +272,15 @@ void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m) if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetPrevNonEmpty(ih, m, p->focus_cell-1); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first-1); + p->first_offset = 0; } } @@ -322,7 +290,7 @@ void iupMatrixScrollLeftUp(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollRightDownFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -334,12 +302,15 @@ void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m) if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetNextNonEmpty(ih, m, p->focus_cell+1); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetNextNonEmpty(ih, m, p->first+1); + p->first_offset = 0; } } @@ -349,7 +320,7 @@ void iupMatrixScrollRightDown(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines (PgLeft) or columns (PgUp) [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPgLeftUpFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -361,12 +332,15 @@ void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m) if (mode == IMAT_SCROLLKEY) { + /* moving focus and eventually scrolling */ int next = iMatrixScrollGetPrevNonEmpty(ih, m, p->focus_cell - (p->last - p->first)); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first - (p->last - p->first)); + p->first_offset = 0; } } @@ -376,7 +350,7 @@ void iupMatrixScrollPgLeftUp(Ihandle* ih, int mode, float pos, int m) -> pos : DO NOT USED -> m : define the mode of operation: lines (PgDown) or columns (PgRight) [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPgRightDown(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPgRightDownFunc(Ihandle* ih, int mode, float pos, int m) { ImatLinColData* p; (void)pos; @@ -388,16 +362,19 @@ void iupMatrixScrollPgRightDown(Ihandle* ih, int mode, float pos, int m) if (mode == IMAT_SCROLLKEY) { - int next = iMatrixScrollGetNextNonEmpty(ih, IMAT_PROCESS_COL, p->focus_cell + (p->last - p->first)); - iMatrixScrollSetFocusScrollToVisible(ih, m, next); + /* moving focus and eventually scrolling */ + int next = iMatrixScrollGetNextNonEmpty(ih, m, p->focus_cell + (p->last - p->first)); + iMatrixScrollSetFocusScrollToVisibleLinCol(ih, m, next); } else /* IMAT_SCROLLBAR */ { + /* always scrolling without changing focus */ p->first = iMatrixScrollGetPrevNonEmpty(ih, m, p->first + (p->last - p->first)); + p->first_offset = 0; } } -void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) +void iupMatrixScrollCrFunc(Ihandle* ih, int unused_mode, float unused_pos, int unused_m) { int oldlin = ih->data->lines.focus_cell; int oldcol = ih->data->columns.focus_cell; @@ -408,13 +385,13 @@ void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unuse /* called only for mode==IMAT_SCROLLKEY */ /* try the normal processing of next cell down */ - iupMatrixScrollRightDown(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN); + iupMatrixScrollRightDownFunc(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN); if(ih->data->lines.focus_cell == oldlin && ih->data->columns.focus_cell == oldcol) { /* If focus was not changed, it was because it is in the last line of the column. Go to the next column of the same line. */ - iupMatrixScrollRightDown(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL); + iupMatrixScrollRightDownFunc(ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL); } } @@ -423,70 +400,51 @@ void iupMatrixScrollCr(Ihandle* ih, int unused_mode, float unused_pos, int unuse -> mode : DO NOT USED -> m : define the mode of operation: lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixScrollPos(Ihandle* ih, int mode, float pos, int m) +void iupMatrixScrollPosFunc(Ihandle* ih, int mode, float pos, int m) { - int scroll_pos, index, vp; - float d; + int scroll_pos; ImatLinColData* p; (void)mode; if (m == IMAT_PROCESS_LIN) - { p = &(ih->data->lines); - d = IupGetFloat(ih, "DY"); - } else - { p = &(ih->data->columns); - d = IupGetFloat(ih, "DX"); - } if (p->num == 1) { p->first = 1; + p->first_offset = 0; return; } scroll_pos = (int)(pos * p->total_size + 0.5); - vp = 0; - for(index = 1; index < p->num; index++) - { - vp += p->sizes[index]; - if (vp > scroll_pos) - break; - } - - if (index == p->num) - { - if (p->num == 1) - index = 1; - else - index = p->num-1; - } - - p->first = index; + /* position first and first_offset, according to scroll pos */ + iupMatrixAuxAdjustFirstFromScrollPos(p, scroll_pos); } -int iupMatrixScroll_CB(Ihandle* ih, int action, float x, float y) +/************************************************************************************/ + +int iupMatrixScroll_CB(Ihandle* ih, int action, float posx, float posy) { if (!iupMatrixIsValid(ih, 0)) return IUP_DEFAULT; switch(action) { - case IUP_SBUP : iupMatrixScrollUp(ih); break; - case IUP_SBDN : iupMatrixScrollDown(ih); break; - case IUP_SBPGUP : iupMatrixScrollPgUp(ih); break; - case IUP_SBPGDN : iupMatrixScrollPgDown(ih); break; - case IUP_SBRIGHT : iupMatrixScrollRight(ih); break; - case IUP_SBLEFT : iupMatrixScrollLeft(ih); break; - case IUP_SBPGRIGHT : iupMatrixScrollPgRight(ih); break; - case IUP_SBPGLEFT : iupMatrixScrollPgLeft(ih); break; - case IUP_SBPOSV : iupMatrixScrollPosVer(ih,y); break; - case IUP_SBPOSH : iupMatrixScrollPosHor(ih,x); break; - case IUP_SBDRAGV : iupMatrixScrollPosVer(ih,y); break; - case IUP_SBDRAGH : iupMatrixScrollPosHor(ih,x); break; + case IUP_SBUP : iupMATRIX_ScrollUp(ih); break; + case IUP_SBDN : iupMATRIX_ScrollDown(ih); break; + case IUP_SBPGUP : iupMATRIX_ScrollPgUp(ih); break; + case IUP_SBPGDN : iupMATRIX_ScrollPgDown(ih); break; + case IUP_SBRIGHT : iupMATRIX_ScrollRight(ih); break; + case IUP_SBLEFT : iupMATRIX_ScrollLeft(ih); break; + case IUP_SBPGRIGHT : iupMATRIX_ScrollPgRight(ih); break; + case IUP_SBPGLEFT : iupMATRIX_ScrollPgLeft(ih); break; + case IUP_SBPOSV : iupMATRIX_ScrollPosVer(ih,posy); break; + case IUP_SBPOSH : iupMATRIX_ScrollPosHor(ih,posx); break; + case IUP_SBDRAGV : iupMATRIX_ScrollPosVer(ih,posy); break; + case IUP_SBDRAGH : iupMATRIX_ScrollPosHor(ih,posx); break; } iupMatrixDrawUpdate(ih); |