diff options
Diffstat (limited to 'iup/srccontrols/matrix')
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_aux.c | 212 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_aux.h | 9 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_cd.h | 12 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_colres.c | 54 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_def.h | 11 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_draw.c | 192 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_edit.c | 35 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_focus.c | 8 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_getset.c | 4 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_getset.h | 2 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_key.c | 18 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_mouse.c | 22 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_numlc.c | 8 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_scroll.c | 282 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmat_scroll.h | 64 | ||||
-rwxr-xr-x | iup/srccontrols/matrix/iupmatrix.c | 90 |
16 files changed, 626 insertions, 397 deletions
diff --git a/iup/srccontrols/matrix/iupmat_aux.c b/iup/srccontrols/matrix/iupmat_aux.c index f8b85bb..1a8df57 100755 --- a/iup/srccontrols/matrix/iupmat_aux.c +++ b/iup/srccontrols/matrix/iupmat_aux.c @@ -24,16 +24,11 @@ #include "iupmat_getset.h" -static int iMatrixAuxIsFullVisibleLast(Ihandle* ih, int m) +int iupMatrixAuxIsFullVisibleLast(ImatLinColData *p) { int i, sum = 0; - ImatLinColData *p; - - if (m == IMAT_PROCESS_LIN) - p = &(ih->data->lines); - else - p = &(ih->data->columns); + sum -= p->first_offset; for(i = p->first; i <= p->last; i++) sum += p->sizes[i]; @@ -43,16 +38,20 @@ static int iMatrixAuxIsFullVisibleLast(Ihandle* ih, int m) return 1; } -int iupMatrixAuxIsCellFullVisible(Ihandle* ih, int lin, int col) +int iupMatrixAuxIsCellStartVisible(Ihandle* ih, int lin, int col) { if(((lin >= ih->data->lines.first) && (lin <= ih->data->lines.last) && (col >= ih->data->columns.first) && (col <= ih->data->columns.last))) { - if (col == ih->data->columns.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_COL)) + if (col == ih->data->columns.first && ih->data->columns.first_offset!=0) + return 0; + if (lin == ih->data->lines.first && ih->data->lines.first_offset!=0) return 0; - if (lin == ih->data->lines.last && !iMatrixAuxIsFullVisibleLast(ih, IMAT_PROCESS_LIN)) + if (col == ih->data->columns.last && !iupMatrixAuxIsFullVisibleLast(&ih->data->columns)) + return 0; + if (lin == ih->data->lines.last && !iupMatrixAuxIsFullVisibleLast(&ih->data->lines)) return 0; return 1; @@ -81,18 +80,98 @@ void iupMatrixAuxGetVisibleCellDim(Ihandle* ih, int lin, int col, int* x, int* y /* find the position where the column starts */ *x = ih->data->columns.sizes[0]; for(i = ih->data->columns.first; i < col; i++) + { *x += ih->data->columns.sizes[i]; - /* find the column size */ + if (i == ih->data->columns.first) + *x -= ih->data->columns.first_offset; + } + + /* get the column size */ *w = ih->data->columns.sizes[col] - 1; + if (col == ih->data->columns.first) + *w -= ih->data->columns.first_offset; /* find the position where the line starts */ *y = ih->data->lines.sizes[0]; for(i = ih->data->lines.first; i < lin; i++) + { *y += ih->data->lines.sizes[i]; - /* find the line size */ + if (i == ih->data->lines.first) + *y -= ih->data->lines.first_offset; + } + + /* get the line size */ *h = ih->data->lines.sizes[lin] - 1; + if (lin == ih->data->lines.first) + *h -= ih->data->lines.first_offset; +} + +void iupMatrixAuxAdjustFirstFromLast(ImatLinColData* p) +{ + int i, sum = 0; + + /* adjust "first" according to "last" */ + + i = p->last; + sum = p->sizes[i]; + while (i>1 && sum < p->visible_size) + { + i--; + sum += p->sizes[i]; + } + + if (i==1 && sum < p->visible_size) + { + /* if there are room for everyone then position at start */ + p->first = 1; + p->first_offset = 0; + } + else + { + /* the "while" found an index for first */ + p->first = i; + + /* position at the remaing space */ + p->first_offset = sum - p->visible_size; + } +} + +void iupMatrixAuxAdjustFirstFromScrollPos(ImatLinColData* p, int scroll_pos) +{ + int index, sp, offset = 0; + + sp = 0; + for(index = 1; index < p->num; index++) + { + sp += p->sizes[index]; + if (sp > scroll_pos) + { + sp -= p->sizes[index]; /* get the previous value */ + offset = scroll_pos - sp; + break; + } + } + + if (index == p->num) + { + if (p->num == 1) + { + /* did NOT go trough the "for" above */ + offset = scroll_pos; + index = 1; + } + else + { + /* go all the way trough the "for" above, but still sp < scroll_pos */ + offset = scroll_pos - sp; + index = p->num-1; + } + } + + p->first = index; + p->first_offset = offset; } /* Calculate the size, in pixels, of the invisible columns/lines, @@ -101,10 +180,11 @@ void iupMatrixAuxGetVisibleCellDim(Ihandle* ih, int lin, int col, int* x, int* y Depends on the first visible column/line. -> m : choose will operate on lines or columns [IMAT_PROCESS_LIN|IMAT_PROCESS_COL] */ -void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m) +void iupMatrixAuxUpdateScrollPos(Ihandle* ih, int m) { + float pos; + int i, sb, scroll_pos; char* POS; - int i, sb, visible_pos; ImatLinColData *p; if (m == IMAT_PROCESS_LIN) @@ -120,33 +200,44 @@ void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m) POS = "POSX"; } - visible_pos = 0; - for(i = 1; i < p->first; i++) - visible_pos += p->sizes[i]; + /* "first" was changed, so update "last" and the scroll pos */ - if (ih->data->canvas.sb & sb) + if (p->total_size <= p->visible_size) { - float pos; + /* the matrix is fully visible */ + p->first = 1; + p->first_offset = 0; + p->last = p->num==1? 1: p->num-1; - if (p->total_size) - { - while ((visible_pos + p->visible_size > p->total_size) && p->first>1) - { - /* invalid position, must recalculate first */ - p->first--; - visible_pos -= p->sizes[p->first]; - } + if (ih->data->canvas.sb & sb) + IupSetAttribute(ih, POS, "0"); - pos = (float)visible_pos/(float)p->total_size; - } - else - pos = 0; + return; + } + + /* must check if it is a valid position */ + scroll_pos = 0; + for(i = 1; i < p->first; i++) + scroll_pos += p->sizes[i]; + scroll_pos += p->first_offset; + + if (scroll_pos + p->visible_size > p->total_size) + { + /* invalid condition, must recalculate so it is valid */ + scroll_pos = p->total_size - p->visible_size; - iupMatrixAuxUpdateLast(p); - IupSetfAttribute(ih, POS, "%.5f", (double)pos); + /* position first and first_offset, according to scroll pos */ + iupMatrixAuxAdjustFirstFromScrollPos(p, scroll_pos); } - else - iupMatrixAuxUpdateLast(p); + + pos = (float)scroll_pos/(float)p->total_size; + + /* update last */ + iupMatrixAuxUpdateLast(p); + + /* update scroll pos */ + if (ih->data->canvas.sb & sb) + IupSetfAttribute(ih, POS, "%g", (double)pos); } /* Calculate which is the last visible column/line of the matrix. @@ -157,18 +248,24 @@ void iupMatrixAuxUpdateLast(ImatLinColData *p) if (p->visible_size > 0) { - /* Find which is the last column/line + /* Find which is the last column/line. Start in the first visible and continue adding the widths - up to the visible size */ + up to the visible size */ + sum -= p->first_offset; for(i = p->first; i < p->num; i++) { - sum += p->sizes[i]; + sum += p->sizes[i]; if(sum >= p->visible_size) break; } if (i == p->num) - p->last = i-1; + { + if (p->num == 1) + p->last = 1; + else + p->last = p->num-1; + } else p->last = i; } @@ -185,7 +282,7 @@ int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col) char* str = iupStrGetMemory(100); char* value; - /* can only be called for valid columns */ + /* can be called for invalid columns (col>numcol) */ sprintf(str, "WIDTH%d", col); value = iupAttribGet(ih, str); @@ -219,7 +316,7 @@ int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col) width = max_width; } } - else if (ih->data->use_title_size) + else if (ih->data->use_title_size && (col>=0 && col<ih->data->columns.num)) { char* title_value = iupMatrixCellGetValue(ih, 0, col); if (title_value) @@ -257,7 +354,7 @@ int iupMatrixAuxGetLineHeight(Ihandle* ih, int lin) char* str = iupStrGetMemory(100); char* value; - /* can only be called for valid lines */ + /* can be called for invalid lines (lin>numlin) */ sprintf(str, "HEIGHT%d", lin); value = iupAttribGet(ih, str); @@ -291,7 +388,7 @@ int iupMatrixAuxGetLineHeight(Ihandle* ih, int lin) height = max_height; } } - else if (ih->data->use_title_size) + else if (ih->data->use_title_size && (lin>=0 && lin<ih->data->lines.num)) { char* title_value = iupMatrixCellGetValue(ih, lin, 0); if (title_value && title_value[0]) @@ -374,7 +471,7 @@ static void iMatrixAuxUpdateVisibleSize(Ihandle* ih, int m) p->visible_size = p->total_size; if (p->total_size) - IupSetfAttribute(ih, D, "%f", (double)p->visible_size/(double)p->total_size); + IupSetfAttribute(ih, D, "%g", (double)p->visible_size/(double)p->total_size); else IupSetAttribute(ih, D, "1.0"); } @@ -390,6 +487,7 @@ void iupMatrixAuxCalcSizes(Ihandle* ih) /* when removing lines the first can be positioned after the last line */ if (ih->data->lines.first > ih->data->lines.num-1) { + ih->data->lines.first_offset = 0; if (ih->data->lines.num==1) ih->data->lines.first = 1; else @@ -397,46 +495,50 @@ void iupMatrixAuxCalcSizes(Ihandle* ih) } if (ih->data->columns.first > ih->data->columns.num-1) { + ih->data->columns.first_offset = 0; if (ih->data->columns.num == 1) ih->data->columns.first = 1; else ih->data->columns.first = ih->data->columns.num-1; } - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + /* make sure scroll pos is consistent */ + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN); ih->data->need_calcsize = 0; } int iupMatrixAuxGetLinColFromXY(Ihandle* ih, int x, int y, int* l, int* c) { - int size, lin, col; + int x_col, y_col, lin, col; - size = ih->data->columns.sizes[0]; /* always visible when non zero */ - if (x < size) + x_col = ih->data->columns.sizes[0]; /* always visible when non zero */ + if (x < x_col) col = 0; /* It is in the column of titles */ else { + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last; col++) /* for all visible columns */ { - size += ih->data->columns.sizes[col]; - if (x < size) + x_col += ih->data->columns.sizes[col]; + if (x < x_col) break; } if (col > ih->data->columns.last) col = -1; } - size = ih->data->lines.sizes[0]; /* always visible when non zero */ - if (y < size) + y_col = ih->data->lines.sizes[0]; /* always visible when non zero */ + if (y < y_col) lin = 0; /* It is in the line of titles */ else { + y_col -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin <= ih->data->lines.last; lin++) /* for all visible lines */ { - size += ih->data->lines.sizes[lin]; - if (y < size) + y_col += ih->data->lines.sizes[lin]; + if (y < y_col) break; } if(lin > ih->data->lines.last) diff --git a/iup/srccontrols/matrix/iupmat_aux.h b/iup/srccontrols/matrix/iupmat_aux.h index 296c1f5..01c77f1 100755 --- a/iup/srccontrols/matrix/iupmat_aux.h +++ b/iup/srccontrols/matrix/iupmat_aux.h @@ -12,19 +12,22 @@ extern "C" { #endif -int iupMatrixAuxIsCellFullVisible(Ihandle* ih, int lin, int col); +int iupMatrixAuxIsFullVisibleLast(ImatLinColData *p); +int iupMatrixAuxIsCellStartVisible(Ihandle* ih, int lin, int col); int iupMatrixAuxIsCellVisible(Ihandle* ih, int lin, int col); void iupMatrixAuxGetVisibleCellDim (Ihandle* ih, int lin, int col, int* x, int* y, int* w, int* h); void iupMatrixAuxCalcSizes(Ihandle* ih); -void iupMatrixAuxUpdateVisiblePos(Ihandle* ih, int m); +void iupMatrixAuxAdjustFirstFromLast(ImatLinColData* p); +void iupMatrixAuxAdjustFirstFromScrollPos(ImatLinColData* p, int scroll_pos); +void iupMatrixAuxUpdateScrollPos(Ihandle* ih, int m); void iupMatrixAuxUpdateLast(ImatLinColData *p); int iupMatrixAuxGetColumnWidth(Ihandle* ih, int col); int iupMatrixAuxGetLineHeight (Ihandle* ih, int lin); -int iupMatrixAuxGetLinColFromXY (Ihandle* ih, int x, int y, int* l, int* c); +int iupMatrixAuxGetLinColFromXY (Ihandle* ih, int x, int y, int* l, int* c); int iupMatrixAuxCallLeaveCellCb (Ihandle* ih); void iupMatrixAuxCallEnterCellCb (Ihandle* ih); diff --git a/iup/srccontrols/matrix/iupmat_cd.h b/iup/srccontrols/matrix/iupmat_cd.h index 1a10f2b..beb616a 100755 --- a/iup/srccontrols/matrix/iupmat_cd.h +++ b/iup/srccontrols/matrix/iupmat_cd.h @@ -11,12 +11,12 @@ extern "C" { #endif -#define IUPMAT_LINE(_ih,_x1,_y1,_x2,_y2) cdCanvasLine((_ih)->data->cddbuffer, (_x1), iupMatrixInvertYAxis(_ih, _y1), (_x2), iupMatrixInvertYAxis(_ih, _y2)) -#define IUPMAT_VERTEX(_ih,_x,_y) cdCanvasVertex((_ih)->data->cddbuffer, (_x), iupMatrixInvertYAxis(_ih, _y)) -#define IUPMAT_BOX(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasBox((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_RECT(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasRect((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_CLIPAREA(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasClipArea((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMatrixInvertYAxis(_ih, _ymin), iupMatrixInvertYAxis(_ih, _ymax)) -#define IUPMAT_TEXT(_ih,_x,_y,_text) cdCanvasText((_ih)->data->cddbuffer, (_x), iupMatrixInvertYAxis(_ih, _y), (_text)) +#define iupMATRIX_LINE(_ih,_x1,_y1,_x2,_y2) cdCanvasLine((_ih)->data->cddbuffer, (_x1), iupMATRIX_INVERTYAXIS(_ih, _y1), (_x2), iupMATRIX_INVERTYAXIS(_ih, _y2)) +#define iupMATRIX_VERTEX(_ih,_x,_y) cdCanvasVertex((_ih)->data->cddbuffer, (_x), iupMATRIX_INVERTYAXIS(_ih, _y)) +#define iupMATRIX_BOX(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasBox((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_RECT(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasRect((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_CLIPAREA(_ih,_xmin,_xmax,_ymin,_ymax) cdCanvasClipArea((_ih)->data->cddbuffer, (_xmin), (_xmax), iupMATRIX_INVERTYAXIS(_ih, _ymin), iupMATRIX_INVERTYAXIS(_ih, _ymax)) +#define iupMATRIX_TEXT(_ih,_x,_y,_text) cdCanvasText((_ih)->data->cddbuffer, (_x), iupMATRIX_INVERTYAXIS(_ih, _y), (_text)) #ifdef __cplusplus } diff --git a/iup/srccontrols/matrix/iupmat_colres.c b/iup/srccontrols/matrix/iupmat_colres.c index d44b7df..79f389e 100755 --- a/iup/srccontrols/matrix/iupmat_colres.c +++ b/iup/srccontrols/matrix/iupmat_colres.c @@ -34,15 +34,17 @@ if so the resize is started */ int iupMatrixColResStart(Ihandle* ih, int x, int y) { - if (ih->data->lines.sizes[0] && y < ih->data->lines.sizes[0] && iupAttribGetBoolean(ih, "RESIZEMATRIX")) + if (ih->data->lines.sizes[0] && + y < ih->data->lines.sizes[0] && + iupAttribGetBoolean(ih, "RESIZEMATRIX")) { - int size, col; + int x_col, col; /* Check if is the column of titles */ - size = ih->data->columns.sizes[0]; - if (abs(size-x) < IMAT_COLRES_TOL) + x_col = ih->data->columns.sizes[0]; + if (abs(x_col-x) < IMAT_COLRES_TOL) { - ih->data->colres_drag_col_start_x = 0; + ih->data->colres_drag_col_start_x = x; ih->data->colres_dragging = 1; ih->data->colres_drag_col_last_x = -1; ih->data->colres_drag_col = 0; @@ -51,12 +53,13 @@ int iupMatrixColResStart(Ihandle* ih, int x, int y) else { /* find the column */ + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last; col++) { - ih->data->colres_drag_col_start_x = size; - size += ih->data->columns.sizes[col]; - if (abs(size-x) < IMAT_COLRES_TOL) + x_col += ih->data->columns.sizes[col]; + if (abs(x_col-x) < IMAT_COLRES_TOL) { + ih->data->colres_drag_col_start_x = x; ih->data->colres_dragging = 1; ih->data->colres_drag_col_last_x = -1; ih->data->colres_drag_col = col; @@ -71,7 +74,8 @@ int iupMatrixColResStart(Ihandle* ih, int x, int y) void iupMatrixColResFinish(Ihandle* ih, int x) { char str[100]; - int width = x - ih->data->colres_drag_col_start_x; + int delta = x - ih->data->colres_drag_col_start_x; + int width = ih->data->columns.sizes[ih->data->colres_drag_col] + delta; if (width < 0) width = 0; @@ -83,8 +87,8 @@ void iupMatrixColResFinish(Ihandle* ih, int x) cdCanvasWriteMode(ih->data->cdcanvas, CD_XOR); cdCanvasForeground(ih->data->cdcanvas, IMAT_RESIZE_COLOR); - cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y1), - ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y1), + ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y2)); cdCanvasWriteMode(ih->data->cdcanvas, CD_REPLACE); } @@ -106,7 +110,8 @@ void iupMatrixColResMove(Ihandle* ih, int x) { int y1, y2; - int width = x - ih->data->colres_drag_col_start_x; + int delta = x - ih->data->colres_drag_col_start_x; + int width = ih->data->columns.sizes[ih->data->colres_drag_col] + delta; if (width < 0) return; @@ -119,12 +124,12 @@ void iupMatrixColResMove(Ihandle* ih, int x) /* If it is not the first time, move old line */ if (ih->data->colres_drag_col_last_x != -1) { - cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y1), - ih->data->colres_drag_col_last_x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y1), + ih->data->colres_drag_col_last_x, iupMATRIX_INVERTYAXIS(ih, y2)); } - cdCanvasLine(ih->data->cdcanvas, x, iupMatrixInvertYAxis(ih, y1), - x, iupMatrixInvertYAxis(ih, y2)); + cdCanvasLine(ih->data->cdcanvas, x, iupMATRIX_INVERTYAXIS(ih, y1), + x, iupMATRIX_INVERTYAXIS(ih, y2)); ih->data->colres_drag_col_last_x = x; cdCanvasWriteMode(ih->data->cdcanvas, CD_REPLACE); @@ -144,20 +149,23 @@ static void iMatrixColResResetMatrixCursor(Ihandle* ih) /* Change the cursor when it passes over a group of the column titles. */ void iupMatrixColResCheckChangeCursor(Ihandle* ih, int x, int y) { - if(ih->data->lines.sizes[0] && y < ih->data->lines.sizes[0] && iupAttribGetBoolean(ih, "RESIZEMATRIX")) + if(ih->data->lines.sizes[0] && + y < ih->data->lines.sizes[0] && + iupAttribGetBoolean(ih, "RESIZEMATRIX")) { /* It is in the column titles area and the resize mode is on */ - int found = 0, size, col; + int found = 0, x_col, col; - size = ih->data->columns.sizes[0]; - if (abs(size - x) < IMAT_COLRES_TOL) + x_col = ih->data->columns.sizes[0]; + if (abs(x_col - x) < IMAT_COLRES_TOL) found = 1; /* line titles */ else { + x_col -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col <= ih->data->columns.last && !found; col++) { - size += ih->data->columns.sizes[col]; - if(abs(size - x) < IMAT_COLRES_TOL) + x_col += ih->data->columns.sizes[col]; + if(abs(x_col - x) < IMAT_COLRES_TOL) found = 1; } } @@ -168,7 +176,7 @@ void iupMatrixColResCheckChangeCursor(Ihandle* ih, int x, int y) iupAttribStoreStr(ih, "_IUPMAT_CURSOR", IupGetAttribute(ih, "CURSOR")); IupSetAttribute(ih, "CURSOR", "RESIZE_W"); } - else /* It is in the empty area after the last column */ + else /* It is in the empty area after the last column, or inside a cell */ iMatrixColResResetMatrixCursor(ih); } else diff --git a/iup/srccontrols/matrix/iupmat_def.h b/iup/srccontrols/matrix/iupmat_def.h index d45acde..225cc16 100755 --- a/iup/srccontrols/matrix/iupmat_def.h +++ b/iup/srccontrols/matrix/iupmat_def.h @@ -49,6 +49,7 @@ typedef struct _ImatLinColData int num; /* Number of columns/lines in the matrix, default/minimum=1, always includes the title */ int num_alloc; /* Number of columns/lines allocated, default=5 */ + int first_offset; /* scroll offset of the first visible column/line from right to left (or the invisible part of the first cell) */ int first; /* First visible column/line */ int last; /* Last visible column/line */ @@ -84,7 +85,7 @@ struct _IcontrolData /* attributes */ int mark_continuous, mark_mode, mark_multiple; - int checkframecolor; + int checkframecolor, hidden_text_marks; /* Mouse and Keyboard AUX */ int leftpressed; /* left mouse button is pressed */ @@ -92,8 +93,8 @@ struct _IcontrolData /* ColRes AUX */ int colres_dragging, /* indicates if it is being made a column resize */ - colres_drag_col, /* column being resized */ - colres_drag_col_start_x, /* position of the start of the column being resized */ + colres_drag_col, /* column being resized, handler is at right of the column */ + colres_drag_col_start_x, /* handler start position */ colres_drag_col_last_x; /* previous position */ /* Mark AUX */ @@ -107,12 +108,14 @@ struct _IcontrolData IFniiIII fgcolor_cb; IFniiIII bgcolor_cb; char *bgcolor, *bgcolor_parent, *fgcolor, *font; /* not need to free */ + + int clip_x1, clip_x2, clip_y1, clip_y2; /* aux for cell clipping */ }; int iupMatrixIsValid(Ihandle* ih, int check_cells); -#define iupMatrixInvertYAxis(_ih, _y) ((_ih)->data->h-1 - (_y)) +#define iupMATRIX_INVERTYAXIS(_ih, _y) ((_ih)->data->h-1 - (_y)) #ifdef __cplusplus diff --git a/iup/srccontrols/matrix/iupmat_draw.c b/iup/srccontrols/matrix/iupmat_draw.c index 7c53fb5..ec3df59 100755 --- a/iup/srccontrols/matrix/iupmat_draw.c +++ b/iup/srccontrols/matrix/iupmat_draw.c @@ -47,13 +47,38 @@ #define IMAT_COMBOBOX_W 16 -typedef int (*IFniiiiiiC)(Ihandle *h, int lin, int col,int x1, int x2, int y1, int y2, cdCanvas* cnv); +typedef int (*IFniiiiiiC)(Ihandle *h, int lin, int col, int x1, int x2, int y1, int y2, cdCanvas* cnv); /**************************************************************************/ /* Private functions */ /**************************************************************************/ +static void iMatrixDrawSetCellClipping(Ihandle* ih, int x1, int x2, int y1, int y2) +{ + int old_clip = cdCanvasClip(ih->data->cddbuffer, CD_QUERY); + if (old_clip == CD_CLIPAREA) + { + cdCanvasGetClipArea(ih->data->cddbuffer, &(ih->data->clip_x1), &(ih->data->clip_x2), &(ih->data->clip_y1), &(ih->data->clip_y2)); + y1 = iupMATRIX_INVERTYAXIS(ih, y1); + y2 = iupMATRIX_INVERTYAXIS(ih, y2); + if (x1 > x2) {int tmp = x1; x1 = x2; x2 = tmp;} + if (y1 > y2) {int tmp = y1; y1 = y2; y2 = tmp;} + if (x1 < ih->data->clip_x1) x1 = ih->data->clip_x1; + if (x2 > ih->data->clip_x2) x2 = ih->data->clip_x2; + if (y1 < ih->data->clip_y1) y1 = ih->data->clip_y1; + if (y2 > ih->data->clip_y2) y2 = ih->data->clip_y2; + cdCanvasClipArea(ih->data->cddbuffer, x1, x2, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + } +} + +static void iMatrixDrawResetCellClipping(Ihandle* ih) +{ + int old_clip = cdCanvasClip(ih->data->cddbuffer, CD_QUERY); + if (old_clip == CD_CLIPAREA) + cdCanvasClipArea(ih->data->cddbuffer, ih->data->clip_x1, ih->data->clip_x2, ih->data->clip_y1, ih->data->clip_y2); +} static int iMatrixDrawGetColAlignment(Ihandle* ih, int col, char* str) { @@ -61,6 +86,8 @@ static int iMatrixDrawGetColAlignment(Ihandle* ih, int col, char* str) sprintf(str, "ALIGNMENT%d", col); align = iupAttribGet(ih, str); if (!align) + align = iupAttribGet(ih, "ALIGNMENT"); + if (!align) { if (col == 0) return IMAT_T_LEFT; @@ -80,16 +107,15 @@ static int iMatrixDrawCallDrawCB(Ihandle* ih, int lin, int col, int x1, int x2, int ret; cdCanvas* old_cnv; - IUPMAT_CLIPAREA(ih, x1, x2, y1, y2); - cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2); old_cnv = cdActiveCanvas(); if (old_cnv != ih->data->cddbuffer) /* backward compatibility code */ cdActivate(ih->data->cddbuffer); - ret = draw_cb(ih, lin, col, x1, x2, iupMatrixInvertYAxis(ih, y1), iupMatrixInvertYAxis(ih, y2), ih->data->cddbuffer); + ret = draw_cb(ih, lin, col, x1, x2, iupMATRIX_INVERTYAXIS(ih, y1), iupMATRIX_INVERTYAXIS(ih, y2), ih->data->cddbuffer); - cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); + iMatrixDrawResetCellClipping(ih); if (old_cnv && old_cnv != ih->data->cddbuffer) /* backward compatibility code */ { @@ -165,28 +191,36 @@ static void iMatrixDrawFrameHorizLineCell(Ihandle* ih, int lin, int col, int x1, { if (ih->data->checkframecolor && (ih->data->callback_mode || ih->data->cells[lin][col].flags & IUPMAT_FRAMEHCOLOR)) { + char* color; unsigned char r,g,b; sprintf(str, "FRAMEHORIZCOLOR%d:%d", lin, col); - if (iupStrToRGB(iupAttribGet(ih, str), &r, &g, &b)) + color = iupAttribGet(ih, str); + if (iupStrEqual(color, "BGCOLOR")) + return; + if (iupStrToRGB(color, &r, &g, &b)) framecolor = cdEncodeColor(r, g, b); } cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_LINE(ih, x1, y, x2, y); /* bottom horizontal line */ + iupMATRIX_LINE(ih, x1, y, x2, y); /* bottom horizontal line */ } static void iMatrixDrawFrameVertLineCell(Ihandle* ih, int lin, int col, int x, int y1, int y2, long framecolor, char* str) { if (ih->data->checkframecolor && (ih->data->callback_mode || ih->data->cells[lin][col].flags & IUPMAT_FRAMEVCOLOR)) { + char* color; unsigned char r,g,b; sprintf(str, "FRAMEVERTCOLOR%d:%d", lin, col); - if (iupStrToRGB(iupAttribGet(ih, str), &r, &g, &b)) + color = iupAttribGet(ih, str); + if (iupStrEqual(color, "BGCOLOR")) + return; + if (iupStrToRGB(color, &r, &g, &b)) framecolor = cdEncodeColor(r, g, b); } cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_LINE(ih, x, y1, x, y2); /* right vertical line */ + iupMATRIX_LINE(ih, x, y1, x, y2); /* right vertical line */ } static void iMatrixDrawFrameRectTitle(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor, char* str) @@ -195,37 +229,43 @@ static void iMatrixDrawFrameRectTitle(Ihandle* ih, int lin, int col, int x1, int x2 -= IMAT_FRAME_W/2; y2 -= IMAT_FRAME_H/2; - iMatrixDrawFrameVertLineCell(ih, lin, col, x2, y1, y2, framecolor, str); /* right vertical line */ + /* right vertical line */ + iMatrixDrawFrameVertLineCell(ih, lin, col, x2, y1, y2, framecolor, str); if (col==0) { - IUPMAT_LINE(ih, x1, y1, x1, y2); /* left vertical line, reuse Foreground */ + /* left vertical line, reuse Foreground */ + iupMATRIX_LINE(ih, x1, y1, x1, y2); x1++; } else if (col==1 && ih->data->columns.sizes[0] == 0) { /* If does not have line titles then draw the left line of the cell frame */ - IUPMAT_LINE(ih, x1, y1, x1, y2-1); + iupMATRIX_LINE(ih, x1, y1, x1, y2-1); x1++; } - cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); /* Titles have a white line near the frame */ - IUPMAT_LINE(ih, x1, y1+1, x1, y2-1); + /* Titles have a white line near the frame, at left */ + cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); + iupMATRIX_LINE(ih, x1, y1+1, x1, y2-1); - iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2, y2, framecolor, str); /* bottom horizontal line */ + /* bottom horizontal line */ + iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2, y2, framecolor, str); if (lin==0) { - IUPMAT_LINE(ih, x1, y1, x2, y1); /* top horizontal line, reuse Foreground */ + /* top horizontal line, reuse Foreground */ + iupMATRIX_LINE(ih, x1, y1, x2, y1); y1++; } else if (lin==1 && ih->data->lines.sizes[0] == 0) { /* If does not have column titles then draw the top line of the cell frame */ - IUPMAT_LINE(ih, x1, y1, x2-1, y1); + iupMATRIX_LINE(ih, x1, y1, x2-1, y1); y1++; } - cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); /* Titles have a white line near the frame */ - IUPMAT_LINE(ih, x1, y1, x2-1, y1); + /* Titles have a white line near the frame, at top */ + cdCanvasForeground(ih->data->cddbuffer, CD_WHITE); + iupMATRIX_LINE(ih, x1, y1, x2-1, y1); } static void iMatrixDrawFrameRectCell(Ihandle* ih, int lin, int col, int x1, int x2, int y1, int y2, long framecolor, char* str) @@ -233,20 +273,20 @@ static void iMatrixDrawFrameRectCell(Ihandle* ih, int lin, int col, int x1, int if (col==1 && ih->data->columns.sizes[0] == 0) { /* If does not have line titles then draw the left line of the cell frame */ - iMatrixDrawFrameVertLineCell(ih, lin, col, x1, y1, y2-1-1, framecolor, str); + iMatrixDrawFrameVertLineCell(ih, lin, col, x1, y1, y2-1, framecolor, str); } if (lin==1 && ih->data->lines.sizes[0] == 0) { /* If does not have column titles then draw the top line of the cell frame */ - iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1-1, y1, framecolor, str); + iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1, y1, framecolor, str); } /* bottom line */ iMatrixDrawFrameHorizLineCell(ih, lin, col, x1, x2-1, y2-1, framecolor, str); /* rigth line */ - iMatrixDrawFrameVertLineCell(ih, lin, col, x2-1, y1, y2-1, framecolor, str); + iMatrixDrawFrameVertLineCell(ih, lin, col, x2-1, y1, y2-2, framecolor, str); } static int iMatrixDrawSortSign(Ihandle* ih, int x2, int y1, int y2, int col, int active, char* str) @@ -274,15 +314,15 @@ static int iMatrixDrawSortSign(Ihandle* ih, int x2, int y1, int y2, int col, int if (iupStrEqualNoCase(sort, "DOWN")) { - IUPMAT_VERTEX(ih, x2 - 5, yc + 2); - IUPMAT_VERTEX(ih, x2 - 1, yc - 2); - IUPMAT_VERTEX(ih, x2 - 9, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 5, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 1, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 9, yc - 2); } else { - IUPMAT_VERTEX(ih, x2 - 1, yc + 2); - IUPMAT_VERTEX(ih, x2 - 9, yc + 2); - IUPMAT_VERTEX(ih, x2 - 5, yc - 2); + iupMATRIX_VERTEX(ih, x2 - 1, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 9, yc + 2); + iupMATRIX_VERTEX(ih, x2 - 5, yc - 2); } cdCanvasEnd(ih->data->cddbuffer); @@ -301,20 +341,20 @@ static void iMatrixDrawComboFeedback(Ihandle* ih, int x2, int y1, int y2, int ac /* feedback background */ iMatrixDrawSetBgColor(ih, 0, 0, 0, active); - IUPMAT_BOX(ih, x1, x2, y1, y2); + iupMATRIX_BOX(ih, x1, x2, y1, y2); /* feedback frame */ cdCanvasForeground(ih->data->cddbuffer, framecolor); - IUPMAT_RECT(ih, x1, x2, y1, y2); + iupMATRIX_RECT(ih, x1, x2, y1, y2); /* feedback arrow */ xh2 = x2 - IMAT_COMBOBOX_W / 2; yh2 = y2 - (y2 - y1) / 2; cdCanvasBegin(ih->data->cddbuffer, CD_FILL); - IUPMAT_VERTEX(ih, xh2, yh2 + 3); - IUPMAT_VERTEX(ih, xh2 + 4, yh2 - 1); - IUPMAT_VERTEX(ih, xh2 - 4, yh2 - 1); + iupMATRIX_VERTEX(ih, xh2, yh2 + 3); + iupMATRIX_VERTEX(ih, xh2 + 4, yh2 - 1); + iupMATRIX_VERTEX(ih, xh2 - 4, yh2 - 1); cdCanvasEnd(ih->data->cddbuffer); } @@ -325,7 +365,7 @@ static void iMatrixDrawBackground(Ihandle* ih, int x1, int x2, int y1, int y2, i y2 -= IMAT_FRAME_H/2; iMatrixDrawSetBgColor(ih, lin, col, marked, active); - IUPMAT_BOX(ih, x1, x2, y1, y2); + iupMATRIX_BOX(ih, x1, x2, y1, y2); } /* Put the cell contents in the screen, using the specified color and alignment. @@ -372,7 +412,7 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in if (text && *text) { int num_line, line_height, total_height; - int charheight, ypos; + int charheight, ypos, hidden_text_marks = 0; num_line = iupStrLineCount(text); iupdrvFontGetCharSize(ih, NULL, &charheight); @@ -380,12 +420,18 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in line_height = charheight; total_height = (line_height + IMAT_PADDING_H/2) * num_line - IMAT_PADDING_H/2 - IMAT_FRAME_H/2; - if (lin==0) + if (lin==0 || ih->data->hidden_text_marks) { int text_w; iupdrvFontGetMultiLineStringSize(ih, text, &text_w, NULL); if (text_w > x2 - x1 + 1 - IMAT_PADDING_W - IMAT_FRAME_W) - alignment = IMAT_T_LEFT; + { + if (lin == 0) + alignment = IMAT_T_LEFT; + + if (ih->data->hidden_text_marks) + hidden_text_marks = 1; + } } /* Set the color used to draw the text */ @@ -395,8 +441,13 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in iMatrixDrawSetFgColor(ih, lin, col, marked); /* Set the clip area to the cell region informed, the text maybe greatter than the cell */ - IUPMAT_CLIPAREA(ih, x1, x2, y1, y2); - cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + if (hidden_text_marks) + { + int crop = iupdrvFontGetStringWidth(ih, "...") + 2; + iMatrixDrawSetCellClipping(ih, x1, x2-crop, y1, y2); + } + else + iMatrixDrawSetCellClipping(ih, x1, x2, y1, y2); cdCanvasNativeFont(ih->data->cddbuffer, iupMatrixGetFont(ih, lin, col)); @@ -417,11 +468,11 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in /* Put the text */ if (alignment == IMAT_T_CENTER) - IUPMAT_TEXT(ih, (x1 + x2) / 2, ypos, text); + iupMATRIX_TEXT(ih, (x1 + x2) / 2, ypos, text); else if(alignment == IMAT_T_LEFT) - IUPMAT_TEXT(ih, x1, ypos, text); + iupMATRIX_TEXT(ih, x1, ypos, text); else - IUPMAT_TEXT(ih, x2, ypos, text); + iupMATRIX_TEXT(ih, x2, ypos, text); } else { @@ -441,11 +492,11 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in /* Draw the text */ if(alignment == IMAT_T_CENTER) - IUPMAT_TEXT(ih, (x1 + x2) / 2, ypos, p); + iupMATRIX_TEXT(ih, (x1 + x2) / 2, ypos, p); else if(alignment == IMAT_T_LEFT) - IUPMAT_TEXT(ih, x1, ypos, p); + iupMATRIX_TEXT(ih, x1, ypos, p); else - IUPMAT_TEXT(ih, x2, ypos, p); + iupMATRIX_TEXT(ih, x2, ypos, p); /* Advance the string */ if (q) p = q + 1; @@ -457,7 +508,15 @@ static void iMatrixDrawCellValue(Ihandle* ih, int x1, int x2, int y1, int y2, in free(newtext); } - cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); + iMatrixDrawResetCellClipping(ih); + + if (hidden_text_marks) + { + cdCanvasTextAlignment(ih->data->cddbuffer, CD_EAST); + ypos = (int)((y1 + y2) / 2.0 - 0.5); + iupMATRIX_TEXT(ih, x2+IMAT_PADDING_W/2, ypos, "..."); + } + } } @@ -522,7 +581,7 @@ static void iMatrixDrawFocus(Ihandle* ih) if (ih->data->lines.focus_cell == 1 && ih->data->lines.sizes[0] == 0) y1++; - cdIupDrawFocusRect(ih, ih->data->cdcanvas, x1, iupMatrixInvertYAxis(ih, y1), x2, iupMatrixInvertYAxis(ih, y2)); + cdIupDrawFocusRect(ih, ih->data->cdcanvas, x1, iupMATRIX_INVERTYAXIS(ih, y1), x2, iupMATRIX_INVERTYAXIS(ih, y2)); } @@ -560,6 +619,11 @@ void iupMatrixDrawLineTitle(Ihandle* ih, int lin1, int lin2) x2 = ih->data->columns.sizes[0]; y1 = ih->data->lines.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, x2, y1, ih->data->h-1); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + + y1 -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin < lin1; lin++) y1 += ih->data->lines.sizes[lin]; @@ -592,6 +656,8 @@ void iupMatrixDrawLineTitle(Ihandle* ih, int lin1, int lin2) y1 = y2; } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); } /* Draw the column titles, visible, between col and lastcol, include it. @@ -623,6 +689,11 @@ void iupMatrixDrawColumnTitle(Ihandle* ih, int col1, int col2) y2 = ih->data->lines.sizes[0]; x1 = ih->data->columns.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, ih->data->w-1, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + + x1 -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col < col1; col++) x1 += ih->data->columns.sizes[col]; @@ -657,6 +728,8 @@ void iupMatrixDrawColumnTitle(Ihandle* ih, int col1, int col2) x1 = x2; } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); } /* Redraw a block of cells of the matrix. Handle marked cells, change @@ -673,13 +746,11 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) IFnii dropcheck_cb; IFniiiiiiC draw_cb; - x1 = 0; x2 = ih->data->w-1; - y1 = 0; y2 = ih->data->h-1; old_x2 = x2; - old_y1 = y1; + old_y1 = 0; old_y2 = y2; if (col1 > ih->data->columns.last || @@ -697,8 +768,14 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) if (lin2 > ih->data->lines.last) lin2 = ih->data->lines.last; + x1 = ih->data->columns.sizes[0]; + y1 = ih->data->lines.sizes[0]; + + iupMATRIX_CLIPAREA(ih, x1, x2, y1, y2); + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); /* wait for background */ + /* Find the initial position of the first column */ - x1 += ih->data->columns.sizes[0]; + x1 -= ih->data->columns.first_offset; for(col = ih->data->columns.first; col < col1; col++) x1 += ih->data->columns.sizes[col]; @@ -708,7 +785,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) x2 += ih->data->columns.sizes[col]; /* Find the initial position of the first line */ - y1 += ih->data->lines.sizes[0]; + y1 -= ih->data->lines.first_offset; for(lin = ih->data->lines.first; lin < lin1; lin++) y1 += ih->data->lines.sizes[lin]; @@ -724,7 +801,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) /* If it was drawn until the last column and remains space in the right of it, then delete this area with the the background color. */ - IUPMAT_BOX(ih, x2, old_x2, old_y1, old_y2); + iupMATRIX_BOX(ih, x2, old_x2, old_y1, old_y2); } if ((lin2 == ih->data->lines.num-1) && (old_y2 > y2)) @@ -735,9 +812,12 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) /* If it was drawn until the last line visible and remains space below it, then delete this area with the the background color. */ - IUPMAT_BOX(ih, 0, old_x2, y2, old_y2); + iupMATRIX_BOX(ih, 0, old_x2, y2, old_y2); } + /* after the background */ + cdCanvasClip(ih->data->cddbuffer, CD_CLIPAREA); + /***** Draw the cell values and frame */ old_y1 = y1; framecolor = cdIupConvertColor(iupAttribGetStr(ih, "FRAMECOLOR")); @@ -775,7 +855,7 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) if (dropcheck_cb && dropcheck_cb(ih, lin, col) == IUP_DEFAULT) { - drop = IMAT_COMBOBOX_W; + drop = IMAT_COMBOBOX_W+IMAT_PADDING_W/2; iMatrixDrawComboFeedback(ih, x2, y1, y2, active, framecolor); } @@ -788,6 +868,8 @@ void iupMatrixDrawCells(Ihandle* ih, int lin1, int col1, int lin2, int col2) x1 = x2; y1 = old_y1; /* must reset also y */ } + + cdCanvasClip(ih->data->cddbuffer, CD_CLIPOFF); } void iupMatrixDraw(Ihandle* ih, int update) diff --git a/iup/srccontrols/matrix/iupmat_edit.c b/iup/srccontrols/matrix/iupmat_edit.c index a7e0a74..551baed 100755 --- a/iup/srccontrols/matrix/iupmat_edit.c +++ b/iup/srccontrols/matrix/iupmat_edit.c @@ -67,7 +67,7 @@ static int iMatrixEditDropDownAction_CB(Ihandle* ih, char* t, int i, int v) if (ret == IUP_CONTINUE) { iupMatrixEditHide(ih_matrix); - iupMatrixDrawUpdate(ih); + iupMatrixDrawUpdate(ih_matrix); } } @@ -137,13 +137,31 @@ static int iMatrixEditCancel(Ihandle* ih, int focus, int update, int ignore) return IUP_DEFAULT; } +static int iMatrixEditDropDown_CB(Ihandle* ih, int state) +{ + /* In Motif if DROPDOWN=YES then when the dropdown button is clicked + the list looses its focus and when the dropped list is closed + the list regain the focus, also when that happen if the list looses its focus + to another control the kill focus callback is not called. */ + Ihandle* ih_matrix = ih->parent; + if (state == 1) + iupAttribSetStr(ih_matrix, "_IUPMAT_DROPDOWN", "1"); + + return IUP_DEFAULT; +} + static int iMatrixEditKillFocus_CB(Ihandle* ih) { Ihandle* ih_matrix = ih->parent; - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) + if (IupGetGlobal("MOTIFVERSION")) { - if (iupAttribGet(ih_matrix, "_IUPMAT_DOUBLE_CLICK")) + if (iupAttribGet(ih_matrix, "_IUPMAT_DROPDOWN") || /* from iMatrixEditDropDown_CB, in Motif */ + iupAttribGet(ih_matrix, "_IUPMAT_DOUBLECLICK")) /* from iMatrixMouseLeftPress, in Motif */ + { + iupAttribSetStr(ih_matrix, "_IUPMAT_DOUBLECLICK", NULL); + iupAttribSetStr(ih_matrix, "_IUPMAT_DROPDOWN", NULL); return IUP_DEFAULT; + } } iupMatrixEditForceHidden(ih_matrix); @@ -200,7 +218,7 @@ int iupMatrixEditShow(Ihandle* ih) /* position the cell to make it visible */ /* If the focus is not visible, a scroll is done for that the focus to be visible */ - if (!iupMatrixAuxIsCellFullVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) + if (!iupMatrixAuxIsCellStartVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) iupMatrixScrollToVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell); /* set attributes */ @@ -235,7 +253,7 @@ int iupMatrixEditShow(Ihandle* ih) ih->data->datah->y = y; if (IupGetGlobal("GTKVERSION")) { - /* In GTK, IupCanvas is not the actual container of the IupText/IupList */ + /* In GTK, IupCanvas is NOT the actual container of the IupText/IupList */ ih->data->datah->x += ih->x; ih->data->datah->y += ih->y; } @@ -366,7 +384,7 @@ static int iMatrixEditTextKeyAny_CB(Ihandle* ih, int c) if (iupMatrixAuxCallLeaveCellCb(ih_matrix) != IUP_IGNORE) { - iupMatrixScrollKeyCr(ih_matrix); + iupMATRIX_ScrollKeyCr(ih_matrix); iupMatrixAuxCallEnterCellCb(ih_matrix); } iupMatrixDrawUpdate(ih_matrix); @@ -399,7 +417,7 @@ static int iMatrixEditDropDownKeyAny_CB(Ihandle* ih, int c) { if (iupMatrixAuxCallLeaveCellCb(ih_matrix) != IUP_IGNORE) { - iupMatrixScrollKeyCr(ih_matrix); + iupMATRIX_ScrollKeyCr(ih_matrix); iupMatrixAuxCallEnterCellCb(ih_matrix); } iupMatrixDrawUpdate(ih_matrix); @@ -440,6 +458,9 @@ void iupMatrixEditCreate(Ihandle* ih) ih->data->droph = IupList(NULL); iupChildTreeAppend(ih, ih->data->droph); + if (IupGetGlobal("MOTIFVERSION")) + IupSetCallback(ih->data->droph, "DROPDOWN_CB", (Icallback)iMatrixEditDropDown_CB); + IupSetCallback(ih->data->droph, "ACTION", (Icallback)iMatrixEditDropDownAction_CB); IupSetCallback(ih->data->droph, "KILLFOCUS_CB", (Icallback)iMatrixEditKillFocus_CB); IupSetCallback(ih->data->droph, "K_ANY", (Icallback)iMatrixEditDropDownKeyAny_CB); diff --git a/iup/srccontrols/matrix/iupmat_focus.c b/iup/srccontrols/matrix/iupmat_focus.c index 3c000f8..0cf680d 100755 --- a/iup/srccontrols/matrix/iupmat_focus.c +++ b/iup/srccontrols/matrix/iupmat_focus.c @@ -35,13 +35,11 @@ int iupMatrixFocus_CB(Ihandle* ih, int focus) if (!iupMatrixIsValid(ih, 1)) return IUP_DEFAULT; - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) + if (IupGetGlobal("MOTIFVERSION")) { - if (focus && iupAttribGet(ih, "_IUPMAT_DOUBLE_CLICK")) - { - iupAttribSetStr(ih, "_IUPMAT_DOUBLE_CLICK", NULL); + if (iupAttribGet(ih, "_IUPMAT_DROPDOWN") || /* from iMatrixEditDropDown_CB, in Motif */ + iupAttribGet(ih, "_IUPMAT_DOUBLECLICK")) /* from iMatrixMouseLeftPress, in Motif */ return IUP_DEFAULT; - } } ih->data->has_focus = focus; diff --git a/iup/srccontrols/matrix/iupmat_getset.c b/iup/srccontrols/matrix/iupmat_getset.c index 34947b6..4424948 100755 --- a/iup/srccontrols/matrix/iupmat_getset.c +++ b/iup/srccontrols/matrix/iupmat_getset.c @@ -313,7 +313,7 @@ char* iupMatrixGetFont(Ihandle* ih, int lin, int col) return font; } -char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels) +char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels_unit) { char* str; int size; @@ -342,7 +342,7 @@ char *iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels) else size -= IMAT_PADDING_H + IMAT_FRAME_H; - if (!pixels) + if (!pixels_unit) { int charwidth, charheight; iupdrvFontGetCharSize(ih, &charwidth, &charheight); diff --git a/iup/srccontrols/matrix/iupmat_getset.h b/iup/srccontrols/matrix/iupmat_getset.h index 9ae3d07..f26e01e 100755 --- a/iup/srccontrols/matrix/iupmat_getset.h +++ b/iup/srccontrols/matrix/iupmat_getset.h @@ -26,7 +26,7 @@ void iupMatrixGetFgRGB(Ihandle* ih, int lin, int col, unsigned char *r, unsigned void iupMatrixCellUpdateValue(Ihandle* ih); -char* iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels); +char* iupMatrixGetSize(Ihandle* ih, int index, int m, int pixels_unit); int iupMatrixCheckCellPos(Ihandle* ih, int lin, int col); diff --git a/iup/srccontrols/matrix/iupmat_key.c b/iup/srccontrols/matrix/iupmat_key.c index ae9ed55..4824438 100755 --- a/iup/srccontrols/matrix/iupmat_key.c +++ b/iup/srccontrols/matrix/iupmat_key.c @@ -37,7 +37,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) int ret = IUP_IGNORE; /* default for processed keys */ /* If the focus is not visible, a scroll is done for that the focus to be visible */ - if (!iupMatrixAuxIsCellFullVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) + if (!iupMatrixAuxIsCellStartVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell)) iupMatrixScrollToVisible(ih, ih->data->lines.focus_cell, ih->data->columns.focus_cell); switch (c) @@ -47,7 +47,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_HOME: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyHome(ih); + iupMATRIX_ScrollKeyHome(ih); ih->data->homekeycount++; iupMatrixAuxCallEnterCellCb(ih); break; @@ -57,7 +57,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_END: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyEnd(ih); + iupMATRIX_ScrollKeyEnd(ih); ih->data->endkeycount++; iupMatrixAuxCallEnterCellCb(ih); break; @@ -71,7 +71,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_LEFT: if (iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyLeft(ih); + iupMATRIX_ScrollKeyLeft(ih); iupMatrixAuxCallEnterCellCb(ih); break; @@ -80,7 +80,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_RIGHT: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyRight(ih); + iupMATRIX_ScrollKeyRight(ih); iupMatrixAuxCallEnterCellCb(ih); break; @@ -89,7 +89,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_UP: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyUp(ih); + iupMATRIX_ScrollKeyUp(ih); iupMatrixAuxCallEnterCellCb(ih); break ; @@ -98,7 +98,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_DOWN: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyDown(ih); + iupMATRIX_ScrollKeyDown(ih); iupMatrixAuxCallEnterCellCb(ih); break; @@ -106,7 +106,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_PGUP: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyPgUp(ih); + iupMATRIX_ScrollKeyPgUp(ih); iupMatrixAuxCallEnterCellCb(ih); break; @@ -114,7 +114,7 @@ int iupMatrixProcessKeyPress(Ihandle* ih, int c) case K_PGDN: if(iupMatrixAuxCallLeaveCellCb(ih) == IUP_IGNORE) break; - iupMatrixScrollKeyPgDown(ih); + iupMATRIX_ScrollKeyPgDown(ih); iupMatrixAuxCallEnterCellCb(ih); break; diff --git a/iup/srccontrols/matrix/iupmat_mouse.c b/iup/srccontrols/matrix/iupmat_mouse.c index 33b5fe7..a3ffa82 100755 --- a/iup/srccontrols/matrix/iupmat_mouse.c +++ b/iup/srccontrols/matrix/iupmat_mouse.c @@ -80,12 +80,18 @@ static void iMatrixMouseLeftPress(Ihandle* ih, int lin, int col, int shift, int if (iupMatrixEditShow(ih)) { - if(ih->data->datah == ih->data->droph) + if (ih->data->datah == ih->data->droph) IupSetAttribute(ih->data->datah, "SHOWDROPDOWN", "YES"); - if (iupStrEqualNoCase(IupGetGlobal("DRIVER"), "Motif")) - if(atoi(IupGetGlobal("MOTIFNUMBER")) < 2203) /* since OpenMotif version 2.2.3 this is not necessary */ - iupAttribSetStr(ih, "_IUPMAT_DOUBLE_CLICK", "1"); + if (IupGetGlobal("MOTIFVERSION")) + { + /* Sequece of focus_cb in Motif from here: + Matrix-Focus(0) - ok + Edit-KillFocus - weird, must avoid using _IUPMAT_DOUBLECLICK + Since OpenMotif version 2.2.3 this is not necessary anymore. */ + if (atoi(IupGetGlobal("MOTIFNUMBER")) < 2203) + iupAttribSetStr(ih, "_IUPMAT_DOUBLECLICK", "1"); + } } } else /* single click */ @@ -182,14 +188,14 @@ int iupMatrixMouseMove_CB(Ihandle* ih, int x, int y) if (ih->data->leftpressed && ih->data->mark_multiple && ih->data->mark_mode != IMAT_MARK_NO) { if ((x < ih->data->columns.sizes[0] || x < IMAT_DRAG_SCROLL_DELTA) && (ih->data->columns.first > 1)) - iupMatrixScrollLeft(ih); + iupMATRIX_ScrollLeft(ih); else if ((x > ih->data->w - IMAT_DRAG_SCROLL_DELTA) && (ih->data->columns.last < ih->data->columns.num-1)) - iupMatrixScrollRight(ih); + iupMATRIX_ScrollRight(ih); if ((y < ih->data->lines.sizes[0] || y < IMAT_DRAG_SCROLL_DELTA) && (ih->data->lines.first > 1)) - iupMatrixScrollUp(ih); + iupMATRIX_ScrollUp(ih); else if ((y > ih->data->h - IMAT_DRAG_SCROLL_DELTA) && (ih->data->lines.last < ih->data->lines.num-1)) - iupMatrixScrollDown(ih); + iupMATRIX_ScrollDown(ih); if (iupMatrixAuxGetLinColFromXY(ih, x, y, &lin, &col)) { diff --git a/iup/srccontrols/matrix/iupmat_numlc.c b/iup/srccontrols/matrix/iupmat_numlc.c index e48720a..6e628b7 100755 --- a/iup/srccontrols/matrix/iupmat_numlc.c +++ b/iup/srccontrols/matrix/iupmat_numlc.c @@ -294,7 +294,7 @@ int iupMatrixSetAddLinAttrib(Ihandle* ih, const char* value) { int base, count, lines_num = ih->data->lines.num; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!iMatrixGetStartEnd(value, &base, &count, lines_num, 0)) @@ -326,7 +326,7 @@ int iupMatrixSetDelLinAttrib(Ihandle* ih, const char* value) { int base, count, lines_num = ih->data->lines.num; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!iMatrixGetStartEnd(value, &base, &count, lines_num, 1)) @@ -366,7 +366,7 @@ int iupMatrixSetAddColAttrib(Ihandle* ih, const char* value) { int base, count, columns_num = ih->data->columns.num; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!iMatrixGetStartEnd(value, &base, &count, columns_num, 0)) @@ -398,7 +398,7 @@ int iupMatrixSetDelColAttrib(Ihandle* ih, const char* value) { int base, count, columns_num = ih->data->columns.num; - if (!ih->handle) /* do not store the action before map */ + if (!ih->handle) /* do not do the action before map */ return 0; if (!iMatrixGetStartEnd(value, &base, &count, columns_num, 1)) 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); diff --git a/iup/srccontrols/matrix/iupmat_scroll.h b/iup/srccontrols/matrix/iupmat_scroll.h index 582442b..45d7417 100755 --- a/iup/srccontrols/matrix/iupmat_scroll.h +++ b/iup/srccontrols/matrix/iupmat_scroll.h @@ -12,54 +12,54 @@ extern "C" { #endif -int iupMatrixScroll_CB(Ihandle* ih, int action, float x, float y); +int iupMatrixScroll_CB(Ihandle* ih, int action, float posx, float posy); void iupMatrixScrollToVisible(Ihandle* ih, int lin, int col); -typedef void (*iupMatrixScrollMoveF)(Ihandle* ih, int mode, float pos, int m); -void iupMatrixScrollMoveCursor(iupMatrixScrollMoveF func, Ihandle* ih, int mode, float pos, int m); +typedef void (*iupMatrixScrollMoveFunc)(Ihandle* ih, int mode, float pos, int m); +void iupMatrixScrollMove(iupMatrixScrollMoveFunc func, Ihandle* ih, int mode, float pos, int m); /* Used only by the macros bellow */ -void iupMatrixScrollHome (Ihandle* ih, int, float, int); -void iupMatrixScrollEnd (Ihandle* ih, int, float, int); -void iupMatrixScrollLeftUp (Ihandle* ih, int, float, int); -void iupMatrixScrollRightDown (Ihandle* ih, int, float, int); -void iupMatrixScrollPgLeftUp (Ihandle* ih, int, float, int); -void iupMatrixScrollPgRightDown(Ihandle* ih, int, float, int); -void iupMatrixScrollPos (Ihandle* ih, int, float, int); -void iupMatrixScrollCr (Ihandle* ih, int, float, int); +void iupMatrixScrollHomeFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollEndFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollLeftUpFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollRightDownFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollPgLeftUpFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollPgRightDownFunc(Ihandle* ih, int, float, int); +void iupMatrixScrollPosFunc (Ihandle* ih, int, float, int); +void iupMatrixScrollCrFunc (Ihandle* ih, int, float, int); /* Mode used to "walk" inside the matrix. It shows if the movement request was from the scrollbar or from a key. - Possible values for the "mode" parameter of the iupMatrixScrollMoveCursor function. + Possible values for the "mode" parameter of the iupMatrixScrollMove function. */ #define IMAT_SCROLLBAR 0 #define IMAT_SCROLLKEY 1 -/* Macros to help during the call of iupMatrixScrollMoveCursor function */ +/* Macros to help during the call of iupMatrixScrollMove function */ /* used in the keyboard processing module */ -#define iupMatrixScrollKeyHome(ih) iupMatrixScrollMoveCursor(iupMatrixScrollHome , ih, IMAT_SCROLLKEY, 0, 0) -#define iupMatrixScrollKeyEnd(ih) iupMatrixScrollMoveCursor(iupMatrixScrollEnd , ih, IMAT_SCROLLKEY, 0, 0) -#define iupMatrixScrollKeyPgUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyPgDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollKeyUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollKeyLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollKeyCr(ih) iupMatrixScrollMoveCursor(iupMatrixScrollCr , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyHome(ih) iupMatrixScrollMove(iupMatrixScrollHomeFunc , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyEnd(ih) iupMatrixScrollMove(iupMatrixScrollEndFunc , ih, IMAT_SCROLLKEY, 0, 0) +#define iupMATRIX_ScrollKeyPgUp(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyPgDown(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyDown(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyRight(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollKeyUp(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollKeyLeft(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLKEY, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollKeyCr(ih) iupMatrixScrollMove(iupMatrixScrollCrFunc , ih, IMAT_SCROLLKEY, 0, 0) /* Used by the scrollbar callback only */ -#define iupMatrixScrollUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollRightDown , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPgUp(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollPgLeft(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgLeftUp , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPgDown(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) -#define iupMatrixScrollPgRight(ih) iupMatrixScrollMoveCursor(iupMatrixScrollPgRightDown, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) -#define iupMatrixScrollPosVer(ih, y) iupMatrixScrollMoveCursor(iupMatrixScrollPos , ih, IMAT_SCROLLBAR, y, IMAT_PROCESS_LIN) -#define iupMatrixScrollPosHor(ih, x) iupMatrixScrollMoveCursor(iupMatrixScrollPos , ih, IMAT_SCROLLBAR, x, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollUp(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollLeft(ih) iupMatrixScrollMove(iupMatrixScrollLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollDown(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollRight(ih) iupMatrixScrollMove(iupMatrixScrollRightDownFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPgUp(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPgLeft(ih) iupMatrixScrollMove(iupMatrixScrollPgLeftUpFunc , ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPgDown(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPgRight(ih) iupMatrixScrollMove(iupMatrixScrollPgRightDownFunc, ih, IMAT_SCROLLBAR, 0, IMAT_PROCESS_COL) +#define iupMATRIX_ScrollPosVer(ih, y) iupMatrixScrollMove(iupMatrixScrollPosFunc , ih, IMAT_SCROLLBAR, posy, IMAT_PROCESS_LIN) +#define iupMATRIX_ScrollPosHor(ih, x) iupMatrixScrollMove(iupMatrixScrollPosFunc , ih, IMAT_SCROLLBAR, posx, IMAT_PROCESS_COL) #ifdef __cplusplus diff --git a/iup/srccontrols/matrix/iupmatrix.c b/iup/srccontrols/matrix/iupmatrix.c index 20d618d..9e379e2 100755 --- a/iup/srccontrols/matrix/iupmatrix.c +++ b/iup/srccontrols/matrix/iupmatrix.c @@ -76,10 +76,13 @@ static int iMatrixSetOriginAttrib(Ihandle* ih, const char* value) return 0; ih->data->columns.first = col; + ih->data->columns.first_offset = 0; ih->data->lines.first = lin; + ih->data->lines.first_offset = 0; - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_COL); - iupMatrixAuxUpdateVisiblePos(ih, IMAT_PROCESS_LIN); + /* when "first" is changed must update scroll pos */ + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_COL); + iupMatrixAuxUpdateScrollPos(ih, IMAT_PROCESS_LIN); iupMatrixDraw(ih, 1); return 0; @@ -109,7 +112,7 @@ static int iMatrixSetShowAttrib(Ihandle* ih, const char* value) if((lin < 1) || (col < 1)) return 0; - if (!iupMatrixAuxIsCellFullVisible(ih, lin, col)) + if (!iupMatrixAuxIsCellStartVisible(ih, lin, col)) iupMatrixScrollToVisible(ih, lin, col); return 0; @@ -173,6 +176,23 @@ static char* iMatrixGetUseTitleSizeAttrib(Ihandle* ih) return "NO"; } +static int iMatrixSetHiddenTextMarksAttrib(Ihandle* ih, const char* value) +{ + if (iupStrBoolean(value)) + ih->data->hidden_text_marks = 1; + else + ih->data->hidden_text_marks = 0; + return 0; +} + +static char* iMatrixGetHiddenTextMarksAttrib(Ihandle* ih) +{ + if (ih->data->hidden_text_marks) + return "YES"; + else + return "NO"; +} + static int iMatrixSetValueAttrib(Ihandle* ih, const char* value) { if (IupGetInt(ih->data->datah, "VISIBLE")) @@ -228,14 +248,14 @@ static char* iMatrixGetMultilineAttrib(Ihandle* ih) static char* iMatrixGetNumLinAttrib(Ihandle* ih) { char* num = iupStrGetMemory(100); - sprintf(num, "%d", ih->data->lines.num-1); + sprintf(num, "%d", ih->data->lines.num-1); /* the attribute does not include the title */ return num; } static char* iMatrixGetNumColAttrib(Ihandle* ih) { char* num = iupStrGetMemory(100); - sprintf(num, "%d", ih->data->columns.num-1); + sprintf(num, "%d", ih->data->columns.num-1); /* the attribute does not include the title */ return num; } @@ -427,13 +447,19 @@ static char* iMatrixGetAlignmentAttrib(Ihandle* ih, const char* name_id) align = iupAttribGet(ih, str); if (!align) { - int col; - if (iupStrToInt(name_id, &col)) + align = iupAttribGet(ih, "ALIGNMENT"); + if (align) + return align; + else { - if (col == 0) - return "ALEFT"; - else - return "ACENTER"; + int col; + if (iupStrToInt(name_id, &col)) + { + if (col == 0) + return "ALEFT"; + else + return "ACENTER"; + } } } @@ -642,7 +668,7 @@ static int iMatrixCreateMethod(Ihandle* ih, void **params) /* Create the edit fields */ iupMatrixEditCreate(ih); - /* defaults */ + /* defaults that are non zero */ ih->data->datah = ih->data->texth; ih->data->mark_continuous = 1; ih->data->columns.num = 1; @@ -656,7 +682,6 @@ static int iMatrixCreateMethod(Ihandle* ih, void **params) ih->data->mark_col1 = -1; ih->data->mark_lin2 = -1; ih->data->mark_col2 = -1; - ih->data->use_title_size = 0; return IUP_NOERROR; } @@ -700,11 +725,34 @@ static void iMatrixUnMapMethod(Ihandle* ih) iupMatrixMemRelease(ih); } +static char* iMatrixGetDefault(Ihandle* ih, const char* name) +{ + int inherit; + char *def_value; + iupClassObjectGetAttributeInfo(ih, name, &def_value, &inherit); + return def_value; +} + +static int iMatrixGetInt(Ihandle* ih, const char* name) +{ + char *value = iupAttribGet(ih, name); + if (!value) value = iMatrixGetDefault(ih, name); + if (value) + { + int i = 0; + if (iupStrToInt(value, &i)) + return i; + } + return 0; +} + static int iMatrixGetNaturalWidth(Ihandle* ih) { int width = 0, num, col; - num = iupAttribGetInt(ih, "NUMCOL_VISIBLE")+1; /* include the title column */ + /* must use this custom function because + the get method for this attribute returns a value with a different meaning */ + num = iMatrixGetInt(ih, "NUMCOL_VISIBLE")+1; /* include the title column */ if (iupAttribGetInt(ih, "NUMCOL_VISIBLE_LAST")) { @@ -716,9 +764,7 @@ static int iMatrixGetNaturalWidth(Ihandle* ih) } else { - if (num > ih->data->columns.num) - num = ih->data->columns.num; - for(col = 0; col < num; col++) + for(col = 0; col < num; col++) /* num can be > numcol */ width += iupMatrixAuxGetColumnWidth(ih, col); } @@ -729,7 +775,9 @@ static int iMatrixGetNaturalHeight(Ihandle* ih) { int height = 0, num, lin; - num = iupAttribGetInt(ih, "NUMLIN_VISIBLE")+1; /* include the title line */ + /* must use this custom function because + the get method for this attribute returns a value with a different meaning */ + num = iMatrixGetInt(ih, "NUMLIN_VISIBLE")+1; /* include the title line */ if (iupAttribGetInt(ih, "NUMLIN_VISIBLE_LAST")) { @@ -741,9 +789,7 @@ static int iMatrixGetNaturalHeight(Ihandle* ih) } else { - if (num > ih->data->lines.num) - num = ih->data->lines.num; - for(lin = 0; lin < num; lin++) + for(lin = 0; lin < num; lin++) /* num can be > numlin */ height += iupMatrixAuxGetLineHeight(ih, lin); } @@ -902,6 +948,8 @@ Iclass* iupMatrixGetClass(void) /* IupMatrix Attributes - GENERAL */ iupClassRegisterAttribute(ic, "USETITLESIZE", iMatrixGetUseTitleSizeAttrib, iMatrixSetUseTitleSizeAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "HIDDENTEXTMARKS", iMatrixGetHiddenTextMarksAttrib, iMatrixSetHiddenTextMarksAttrib, IUPAF_SAMEASSYSTEM, "NO", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); + iupClassRegisterAttribute(ic, "FRAMECOLOR", NULL, NULL, IUPAF_SAMEASSYSTEM, "100 100 100", IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "READONLY", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); iupClassRegisterAttribute(ic, "RESIZEMATRIX", NULL, NULL, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT); |