From a01614cb423b0d39dcf8980ba4d3dc9163e23868 Mon Sep 17 00:00:00 2001 From: cxl Date: Tue, 1 Dec 2020 13:03:42 +0000 Subject: [PATCH] ide: cosmetics, GridCtrl: Selection refactored to follow spreadsheet model git-svn-id: svn://ultimatepp.org/upp/trunk@15558 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/CtrlCore.h | 2 + uppsrc/CtrlCore/Frame.cpp | 10 + uppsrc/GridCtrl/GridCtrl.cpp | 1600 +------------------------------- uppsrc/GridCtrl/GridCtrl.h | 11 +- uppsrc/GridCtrl/GridCtrl.upp | 4 + uppsrc/GridCtrl/GridKey.cpp | 216 +++++ uppsrc/GridCtrl/GridMouse.cpp | 577 ++++++++++++ uppsrc/GridCtrl/GridPaint.cpp | 513 ++++++++++ uppsrc/GridCtrl/GridSelect.cpp | 258 +++++ uppsrc/ide/AutoSetup.cpp | 14 - uppsrc/ide/Common/ComDlg.cpp | 28 +- uppsrc/ide/Common/Common.h | 2 - uppsrc/ide/ide.h | 1 + 13 files changed, 1610 insertions(+), 1626 deletions(-) create mode 100644 uppsrc/GridCtrl/GridKey.cpp create mode 100644 uppsrc/GridCtrl/GridMouse.cpp create mode 100644 uppsrc/GridCtrl/GridPaint.cpp create mode 100644 uppsrc/GridCtrl/GridSelect.cpp diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index f8bd9d39c..2a04dcd94 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -208,6 +208,8 @@ CtrlFrame& BottomSeparatorFrame(); CtrlFrame& LeftSeparatorFrame(); CtrlFrame& RightSeparatorFrame(); +CtrlFrame& RightGapFrame(); + void LayoutFrameLeft(Rect& r, Ctrl *ctrl, int cx); void LayoutFrameRight(Rect& r, Ctrl *ctrl, int cx); void LayoutFrameTop(Rect& r, Ctrl *ctrl, int cy); diff --git a/uppsrc/CtrlCore/Frame.cpp b/uppsrc/CtrlCore/Frame.cpp index 4c1bcc094..a680f2b13 100644 --- a/uppsrc/CtrlCore/Frame.cpp +++ b/uppsrc/CtrlCore/Frame.cpp @@ -107,11 +107,21 @@ class RightSeparatorFrameCls : public CtrlFrame { virtual void FrameAddSize(Size& sz) { sz.cx += 2; } }; +class RightGapFrameCls : public CtrlFrame { + virtual void FrameLayout(Rect& r) { r.right -= DPI(2); } + virtual void FramePaint(Draw& w, const Rect& r) { + w.DrawRect(r.right - DPI(2), r.top, DPI(2), r.Height(), SColorFace()); + } + virtual void FrameAddSize(Size& sz) { sz.cx += DPI(2); } +}; + CtrlFrame& BottomSeparatorFrame() { return Single(); } CtrlFrame& TopSeparatorFrame() { return Single(); } CtrlFrame& RightSeparatorFrame() { return Single(); } CtrlFrame& LeftSeparatorFrame() { return Single(); } +CtrlFrame& RightGapFrame() { return Single(); } + CH_INT(FrameButtonWidth, DPI(17)); CH_INT(ScrollBarArrowSize, FrameButtonWidth()); diff --git a/uppsrc/GridCtrl/GridCtrl.cpp b/uppsrc/GridCtrl/GridCtrl.cpp index e5dd1cafb..fcc4d70ae 100644 --- a/uppsrc/GridCtrl/GridCtrl.cpp +++ b/uppsrc/GridCtrl/GridCtrl.cpp @@ -1,4 +1,5 @@ #include +#include namespace Upp { @@ -181,7 +182,8 @@ GridCtrl::GridCtrl() : holder(*this) osz.cx = osz.cy = -1; livecur.x = livecur.y = -1; leftpnt.x = leftpnt.y = -1; - shiftpos.x = shiftpos.y = -1; + + anchor = Null; fixed_width = 0; fixed_height = 0; @@ -197,7 +199,6 @@ GridCtrl::GridCtrl() : holder(*this) /* add indicator, total_cols = 1 */ AddColumn("", 0); - shiftmode = false; recalc_cols = false; recalc_rows = false; selected_rows = 0; @@ -275,7 +276,6 @@ GridCtrl::GridCtrl() : holder(*this) resize_panel.WhenClose = Proxy(WhenClose); resizing = false; - selecting = false; is_clipboard = false; enabled = true; sync_flag = 0; @@ -729,7 +729,6 @@ void GridCtrl::SetClipboard(bool all, bool silent) gc.maxpos = maxpos; bool row_selected = select_row && IsSelected(curpos.y, false); - gc.shiftmode = row_selected ? true : shiftmode; WriteClipboardFormat(gc); AppendClipboardText(header + body); @@ -1116,507 +1115,6 @@ GridCtrl::Item& GridCtrl::GetItemSize(int &r, int &c, int &x, int &y, int &cx, i return *it; } -void GridCtrl::Paint(Draw &w) -{ - static int paintcnt = 0; - - Font stdfont(StdFont()); - - Size sz = GetSize(); - Rect rc = Rect(sz); //w.GetClip() - it always returns view rect now. bug?? - - if(!ready) - { - w.DrawRect(rc, SColorPaper); - return; - } - - int i, j, cx, cy, x, y; - bool skip; - Rect r; - - LG(0, "---- Paint(%d)", ++paintcnt); - - if(total_cols <= 1 || total_rows == 0) - { - LG(0, "---- Paint(%d) Empty.", paintcnt); - w.DrawRect(sz, SColorPaper); - return; - } - - if(UpdateCols() || UpdateRows()) - UpdateSizes(); - - if(firstCol < 0) firstCol = GetFirstVisCol(fixed_width); - if(firstRow < 0) firstRow = GetFirstVisRow(fixed_height); - - LG(0, "firstCol %d", firstCol); - LG(0, "firstRow %d", firstRow); - - int en = IsShowEnabled() ? 0 : GD::READONLY; - - //--------------------------------------------------------------------------------------- - - if(fixed_width > 0 && fixed_height > 0) - { - w.Clip(0, 0, fixed_width, fixed_height); - dword style = chameleon ? GD::CHAMELEON : 0; - - display->PaintFixed(w, 1, 1, 0, 0, fixed_width, fixed_height, - Value(""), - style, stdfont, false, false, - 0, -1, 0, - true); - w.End(); - } - - r.Set(fixed_width, 0, sz.cx, summary_row ? sz.cy : fixed_height); - - if(w.IsPainting(r) && total_cols > 1) - { - LG(0, "Top header"); - w.Clip(r); - - x = hitems[total_cols - 1].nRight(sbx); - int rx = x; - - int firstcol = indicator ? 0 : (fixed_cols > 1 ? 1 : firstVisCol); - if(firstCol < 0) firstCol = 0; - int jfc = chameleon ? 0 : firstCol; - - for(i = 0; i < fixed_rows; i++) - { - for(j = jfc; j < total_cols; j++) - { - ItemRect& hi = hitems[j]; - - if(hi.hidden) - continue; - - int jj = j; - Item &it = GetItemSize(i, j, x, y, cx, cy, skip, true, false); - if(skip) - continue; - - if(x >= rc.right) - break; - - if(w.IsPainting(x, y, cx, cy)) - { - GridDisplay * gd = it.display ? it.display : display; - - dword style = hi.style | hi.halign; - if(i > 0) style &= ~GD::HIGHLIGHT; - if(chameleon) - style |= GD::CHAMELEON; - - Font fnt(stdfont); - gd->SetLeftImage(hi.img); - gd->ReverseSortIcon(reverse_sort_icon); - gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, - i == 0 ? it.val : GetConvertedColumn(hi.id, it.val), - style | en, IsNull(hi.hfnt) ? fnt : hi.hfnt, false, false, - i == 0 ? hi.sortmode : 0, - hi.sortcol, - sortOrder.GetCount(), - true); - - it.rcx = gd->real_size.cx; - it.rcy = gd->real_size.cy; - } - - if(summary_row && i == 0) - { - cy = GD_HDR_HEIGHT; - y = sz.cy - cy; - - if(w.IsPainting(x, y, cx, cy)) - { - Item &it = summary[hi.id]; - GridDisplay * gd = it.display ? it.display : display; - - dword style = en | hi.halign; - if(chameleon) - style |= GD::CHAMELEON; - - String s; - if(hi.sop != SOP_NONE && !hi.sopfrm.IsEmpty() && !IsNull(it.val)) - s = Format(hi.sopfrm, it.val); - else - s = IsString(it.val) ? it.val : StdConvert().Format(it.val); - gd->SetLeftImage(Null); - //gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, s, - // style | en, stdfont, false, false, 0, -1, 0, true); - Color fg = Black; - Color bg = Blend(Blue, White, 240); - w.DrawRect(x, y, cx, 1, Gray); - Font fnt(stdfont); - - if(style & GD::READONLY) - { - bg = Blend(bg, SGray(), 40); - fg = Blend(fg, SGray(), 200); - } - - gd->Paint(w, x, y + 1, cx, cy - 1, s, style, fg, bg, fnt.Bold(), false, 0, 0); - - it.rcx = gd->real_size.cx; - it.rcy = gd->real_size.cy; - } - } - } - } - if(rx < sz.cx || chameleon) - { - int cx = sz.cx - rx + 1; - dword style = 0; - if(chameleon) - { - cx = max(10, cx); - style = GD::CHAMELEON; - } - display->PaintFixed(w, 0, 1, rx, 0, cx, fixed_height, - Value(""), - style, stdfont, false, false, - 0, -1, 0, - true); - if(summary_row) - { - Color fg = Black; - Color bg = Blend(Blue, White, 240); - w.DrawRect(rx, y, cx, 1, Gray); - - if(style & GD::READONLY) - { - bg = Blend(bg, SGray(), 40); - fg = Blend(fg, SGray(), 200); - } - display->Paint(w, rx, y + 1, cx, GD_HDR_HEIGHT - 1, Value(""), style, fg, bg, stdfont, false, 0, 0); - } - } - - w.End(); - } - //--------------------------------------------------------------------------------------- - - bool can_paint = firstCol >= 0 && firstRow >= 0; - r.Set(0, fixed_height, fixed_width, sz.cy); - - if(can_paint && w.IsPainting(r)) - { - LG(0, "Left header"); - w.Clip(r); - y = vitems[total_rows - 1].nBottom(sby); - - if(y < sz.cy) - w.DrawRect(Rect(0, y, fixed_width, sz.cy - summary_height), SColorPaper); - - for(i = 0; i < fixed_cols; i++) - { - bool firstx = (i == !indicator); - bool indicator = (i == 0); - int id = hitems[i].id; - - for(j = firstRow; j < total_rows; j++) - { - ItemRect& vi = vitems[j]; - - if(vi.hidden) - continue; - - Item &it = GetItemSize(j, i, x, y, cx, cy, skip, false, true); - - if(skip) - continue; - - if(y >= rc.bottom) - break; - - if(w.IsPainting(x, y, cx, cy)) - { - GridDisplay * gd = it.display ? it.display : display; - - dword style = vi.style; - if(i > 0) style &= ~GD::HIGHLIGHT; - if(chameleon) - style |= GD::CHAMELEON; - - Font fnt(stdfont); - gd->PaintFixed(w, firstx, j == 0, x, y, cx, cy, - GetConvertedColumn(id, it.val), - style | en, IsNull(vi.hfnt) ? fnt : vi.hfnt, - indicator, false, 0, -1, 0, false); - - it.rcx = gd->real_size.cx; - it.rcy = gd->real_size.cy; - } - } - - if(summary_row) - { - j = 0; - cy = GD_HDR_HEIGHT; - y = sz.cy - cy; - if(w.IsPainting(x, y, cx, cy)) - { - Item& it = summary[hitems[i].id]; - GridDisplay * gd = it.display ? it.display : display; - - dword style = vitems[j].style; - if(chameleon) - style |= GD::CHAMELEON; - -// gd->PaintFixed(w, firstx, true, x, y, cx, cy, -// GetConvertedColumn(id, it.val), -// style | en, stdfont, -// false, false, 0, -1, 0, false); -// - Color fg = Black; - Color bg = Blend(Blue, White, 240); - w.DrawRect(x, y, cx, 1, Gray); - Font fnt(stdfont); - gd->Paint(w, x, y + 1, cx, cy - 1, GetConvertedColumn(id, it.val), style | en, fg, bg, fnt.Bold(), false, 0, 0); - - } - } - } - - w.End(); - } - - //--------------------------------------------------------------------------------------- - - r.Set(fixed_width, fixed_height, sz.cx, sz.cy - summary_height); - - if(can_paint && w.IsPainting(r)) - { - LG(0, "Body"); - w.Clip(r); - - x = hitems[total_cols - 1].nRight(sbx); - y = vitems[total_rows - 1].nBottom(sby); - - if(x < sz.cx) w.DrawRect(Rect(max(x, rc.left), max(fixed_height, rc.top), sz.cx, sz.cy), SColorPaper); - if(y < sz.cy) w.DrawRect(Rect(max(fixed_width, rc.left), max(y, rc.top), sz.cx, sz.cy), SColorPaper); - - bool hasfocus = HasFocus() || holder.HasFocusDeep(); - - for(i = max(firstRow, fixed_rows); i < total_rows; i++) - { - ItemRect& vi = vitems[i]; - if(vi.hidden) continue; - - bool even = coloring_mode == 2 ? (i - vi.n - fixed_rows) & 1 : false; - - for(j = max(firstCol, fixed_cols); j < total_cols; j++) - { - const ItemRect& hi = hitems[j]; - - if(hi.hidden) - continue; - - Item &it = GetItemSize(i, j, x, y, cx, cy, skip); - if(skip) - continue; - - if(y >= rc.bottom) - goto end_paint; - - if(x >= rc.right) - break; - - if(!w.IsPainting(0, y, sz.cx, cy)) - break; - - if(w.IsPainting(x, y, cx, cy)) - { - bool iscur = draw_focus ? (i == curpos.y && j == curpos.x) : false; - - if(coloring_mode == 1) - even = (j - hi.n - fixed_cols) & 1; - - int id = hi.id; - - dword style = en | (select_row ? vi.style : it.style) | hi.balign; - dword istyle = it.style; - - if(hitems[j].wrap) - style |= GD::WRAP; - if(ctrlpos.y == i && edits[id].ctrl && edits[id].ctrl->IsShown()) - style |= GD::NOTEXT; - if(it.ctrl) - style |= GD::NOTEXT; - - if(coloring_mode > 0) - style |= (even ? GD::EVEN : GD::ODD); - if(hasfocus) - style |= GD::FOCUS; - - Color cfg; - Color cbg; - - Font fnt = StdFont(); - GridDisplay* gd; - Value val = GetItemValue(it, id, hi, vi); - GetItemAttrs(it, val, i, j, vi, hi, style, gd, cfg, cbg, fnt); - - Color fg = SColorText; - Color bg = SColorPaper; - - bool custom = true; - - if(style & GD::CURSOR) - { - if(style & GD::FOCUS) - { - fg = iscur ? Blend(bg_focus, Black, 230) : fg_focus; - bg = iscur ? Blend(bg_focus, White, 230) : bg_focus; - } - else - { - bg = Blend(SColorDisabled, bg); - } - custom = false; - } - else if(style & GD::LIVE) - { - fg = fg_live; - bg = bg_live; - custom = false; - } - else if(istyle & GD::FOUND) - { - fg = fg_found; - bg = bg_found; - custom = false; - } - else if(style & GD::SELECT) - { - fg = fg_select; - bg = bg_select; - custom = false; - } - else if(style & GD::EVEN) - { - fg = fg_even; - bg = bg_even; - } - else if(style & GD::ODD) - { - fg = fg_odd; - bg = bg_odd; - } - - if(custom) - { - if(!IsNull(cfg)) fg = cfg; - if(!IsNull(cbg)) bg = cbg; - } - - if(style & GD::READONLY) - { - bg = Blend(bg, SGray(), 40); - fg = Blend(fg, SGray(), 200); - } - - gd->SetBgImage(vi.img); - gd->col = j - fixed_rows; - gd->row = i - fixed_cols; - gd->parent = this; - - val = GetAttrTextVal(val); - - gd->Paint(w, x, y, cx, cy, - val, style, - fg, bg, fnt, it.style & GD::FOUND, it.fs, it.fe); - - it.rcx = gd->real_size.cx; - it.rcy = gd->real_size.cy; - - if(vert_grid) - { - bool skip = false; - if(!draw_last_vert_line && j == total_cols - 1) - skip = true; - - if(!skip) - w.DrawRect(x + cx - 1, y, 1, cy, fg_grid); - } - if(horz_grid) - { - bool skip = false; - if(!draw_last_horz_line && i == total_rows - 1) - skip = true; - - if(!skip) - w.DrawRect(x, y + cy - 1, cx, 1, fg_grid); - } - - if(iscur && draw_focus) - Upp::DrawFocus(w, x, y, cx, cy); - } - //if(curpos.y == i) - // DrawFocus(w, hitems[fixed_cols].nLeft(), y, hitems[total_cols - 1].nRight() - 1, cy - 1); - } - } - - end_paint: - - w.End(); - - lastCol = j - 1; - lastRow = i - 1; - } - - - if(moving_header && fixed_top_click && curSplitCol >= 0) - { - r.Set(fixed_width, 0, sz.cx, fixed_height); - w.Clip(r); - bool lastcol = curSplitCol == lastVisCol; - - int cp = curSplitCol; - if(!lastcol) - while(++cp < total_cols && hitems[cp].hidden); - - int cx = hitems[cp].nWidth() / 2; - int x = lastcol ? hitems[curSplitCol].nLeft(sbx) + cx - : hitems[curSplitCol].nRight(sbx) - 1; - DrawFatFrame(w, x, 0, cx, vitems[fixed_rows - 1].nBottom(), moving_allowed ? LtBlue : Red, 2); - w.End(); - } - - if(moving_header && fixed_left_click) - { - int dy = curSplitRow == lastVisRow ? -2 : -1; - int y = curSplitRow >= 0 ? vitems[curSplitRow].nBottom(sby) + dy : 0; - if(y >= fixed_height - 1) - DrawVertDragLine(w, y, hitems[fixed_cols - 1].nRight(), 0, moving_allowed ? LtBlue : Red); - } - - if(moving_body) - { - int dy = curSplitRow == lastVisRow ? -2 : -1; - int y = curSplitRow >= 0 ? vitems[curSplitRow].nBottom(sby) + dy : 0; - if(y >= fixed_height - 1) - DrawVertDragLine(w, y, sz.cx, fixed_width - 1, LtBlue); - } - - if(search_display && !search_string.IsEmpty()) - { - Size tsz = GetTextSize(search_string, StdFont()); - w.DrawRect(Rect(0, sz.cy - tsz.cy - 4, tsz.cx + 4, sz.cy), SRed); - w.DrawText(2, sz.cy - tsz.cy - 2, search_string, StdFont(), SYellow); - } - - if(!can_paint) - w.DrawRect(Rect(0, total_cols > 1 ? fixed_height : 0, sz.cx, sz.cy), SColorPaper); - if(++paint_flag > 100) - paint_flag = 0; - - LG(0, "---- Paint(%d).", paintcnt); -} - void GridCtrl::DrawHorzDragLine(Draw &w, int pos, int cx, int size, Color c) { //w.DrawRect(pos, 0, cx / 2, size - 1, Color(100, 100, 100, 100); @@ -1878,232 +1376,6 @@ void GridCtrl::SetColCount(int n, int size) AddColumn("", size, false); } -void GridCtrl::MouseMove(Point p, dword keyflags) -{ - mouse_move = true; - - if(resizing) - { - int si, lp, mp, off; - RectItems *its; - static int sub = 0; - - if(resizeCol) - { - mp = p.x; - lp = leftpnt.x; - si = splitCol; - its = &hitems; - bool top = fixed_top_click || (!fixed_left_click && full_col_resizing); - off = top ? sbx : 0; - } - else - { - mp = p.y; - lp = leftpnt.y; - si = splitRow; - its = &vitems; - bool left = fixed_left_click || (!fixed_top_click && full_row_resizing); - off = left ? sby : 0; - } - - int right = (*its)[si].nRight(off); - - if(just_clicked) - { - sub = right - lp; - just_clicked = false; - } - - if(SetDiffItemSize(resizeCol, *its, si, mp - right + sub)) - { - Split(GS_MOVE); - } - - return; - } - else if(fixed_click) - { - if((fixed_top_click && !moving_cols) || - (fixed_left_click && !moving_rows) || - moveCol < 0 || moveRow < 0) - return; - - if(!moving_header) - { - int diffx = p.x - leftpnt.x; - int diffy = p.y - leftpnt.y; - if(abs(diffx) < 5 && abs(diffy) < 5) - return; - - p -= Point(diffx, diffy); - - moving_header = true; - int idx = hitems[moveCol].id; - int idy = vitems[moveRow].id; - pophdr.val = idy > 0 ? GetConvertedColumn(moveCol, items[idy][idx].val) : items[idy][idx].val; - - if(fixed_top_click) - { - pophdr.sortmode = hitems[moveCol].sortmode; - pophdr.sortcol = hitems[moveCol].sortcol; - pophdr.sortcnt = sortOrder.GetCount(); - - UpdateHighlighting(GS_POPUP, p); - } - else - { - pophdr.sortmode = 0; - pophdr.sortcol = -1; - pophdr.sortcnt = 0; - } - - dx = hitems[moveCol].nLeft(fixed_top_click ? sbx : 0) - p.x; - dy = vitems[moveRow].nTop(fixed_left_click ? sby : 0) - p.y; - } - - - Point pt = p + GetScreenRect().TopLeft() + GetBarOffset(); - - pophdr.display = display; - pophdr.chameleon = chameleon; - pophdr.PopUp(this, pt.x + dx, pt.y + dy, hitems[moveCol].nWidth(), vitems[moveRow].nHeight()); - - if(fixed_top_click && curSplitCol != oldMoveCol) - { - moving_allowed = CanMoveCol(moveCol, curSplitCol); - RefreshTop(); - //Refresh(oldMoveCol >= 0 ? hitems[oldMoveCol].nRight(sbx) : 0, 0, hitems[curSplitCol].nRight(sbx), fixed_height); - oldMoveCol = curSplitCol; - } - - if(fixed_left_click && curSplitRow != oldMoveRow) - { - Refresh(0, 0, fixed_width, fixed_height); - RefreshLeft(); - oldMoveRow = curSplitRow; - } - return; - } - - if(leftpnt != p && p.y < fixed_height) - { - UpdateHighlighting(GS_MOVE, p); - } - - if(live_cursor && popup.IsOpen()) - { - LG(2, "MouseMove:LiveCursor"); - if(IsMouseBody(p)) - SetCursor0(p, CU_MOUSE | CU_HIGHLIGHT); - else - SetCursor0(-1, -1, CU_HIGHLIGHT); - } - - if(HasCapture()) - { - if(!moving_body) - { - if(keyflags & K_SHIFT) - { - if(SetCursor0(p, CU_MOUSE)) - { - DoShiftSelect(); - selecting = true; - } - return; - } - - bool select = true; - if(select_row && !multi_select) - select = false; - - if(select && (keyflags & K_CTRL)) - { - if(SetCursor0(p, CU_MOUSE)) - { - DoCtrlSelect(); - selecting = true; - } - return; - } - } - - if(moveCol < 0 || moveRow < 0) - return; - - if(!dragging) - return; - - if(!moving_body) - { - popup.Close(); - - if(!top_click && valid_cursor && - p.x < total_width && - p.y < total_height && - (abs(p.y - leftpnt.y) > 5 || - abs(p.x - leftpnt.x) > 5)) - moving_body = true; - - oldMoveRow = -1; - } - else - { - Point pt = p + GetScreenRect().TopLeft(); - - int row = curSplitRow - fixed_rows + 2; - if(select_row) - { - int count = max(1, selected_rows); - - if(vitems[curpos.y].IsSelect()) - popup.val = Format(t_("Moving selection (%d %s) before row %d"), count, count == 1 ? t_("row") : t_("rows"), row); - else - popup.val = Format(t_("Moving row %d before row %d"), curpos.y - fixed_rows + 1, row); - } - else - { - int count = max(1, selected_items); - popup.val = Format(t_("Moving %d %s before row %d"), count, count == 1 ? t_("cell") : t_("cells"), row); - } - - int px = pt.x + 15; - int py = pt.y + GD_ROW_HEIGHT; - - popup.gd = display; - popup.gd->row = 0; - popup.gd->col = 0; - popup.fg = SColorText; - popup.bg = SColorPaper; - popup.fnt = StdFont(); - popup.style = 0; - popup.PopUp(this, px, py, GetTextSize((String) popup.val, StdFont()).cx + 10, GD_ROW_HEIGHT); - SetFocus(); - - if(curSplitRow != oldMoveRow || scrollLeftRight) - { - int dy = sby; - if(oldMoveRow >= 0) - Refresh(Rect(0, vitems[oldMoveRow].nBottom(dy) - 5, GetSize().cx, vitems[oldMoveRow].nBottom(dy) + 5)); - else - Refresh(Rect(0, 0, GetSize().cx, 5)); - if(curSplitRow >= 0) - Refresh(Rect(0, vitems[curSplitRow].nBottom(dy) - 5, GetSize().cx, vitems[curSplitRow].nBottom(dy) + 5)); - else - Refresh(Rect(0, 0, GetSize().cx, 5)); - - oldMoveRow = curSplitRow; - popup.Refresh(); - - scrollLeftRight = false; - } - } - } - else - SyncPopup(); -} - void GridCtrl::SyncPopup() { if(!IsPopUp() && popups) @@ -2195,295 +1467,6 @@ void GridCtrl::SyncPopup() } } -void GridCtrl::LeftDown(Point p, dword keyflags) -{ - //popup.Close(); - SetCapture(); - leftpnt = p; - just_clicked = true; - selecting = false; - - fixed_top_click = p.x >= fixed_width && p.y < fixed_height; - fixed_left_click = p.x < fixed_width && p.y >= fixed_height; - fixed_click = fixed_top_click || fixed_left_click; - top_click = p.y < fixed_height; - - resizing = curResizeCol || curResizeRow; - - if(resizing) - { - popup.Close(); - - splitCol = curSplitCol; - splitRow = curSplitRow; - resizeCol = curResizeCol; - resizeRow = curResizeRow; - - Split(GS_DOWN); - return; - } - else if(fixed_click) - { - moveCol = oldMoveCol = GetMouseCol(p, fixed_top_click, 1); - moveRow = oldMoveRow = GetMouseRow(p, fixed_left_click, 1); - return; - } - - SetFocus(); - - if(IsEmpty() || IsReadOnly()) - return; - - bool is_shift = keyflags & K_SHIFT; - bool is_ctrl = keyflags & K_CTRL; - - CurState cs = SetCursor0(p, CU_MOUSE | CU_HIDECTRLS); - bool state_change = cs.IsValid() && !cs.IsNew() && (is_ctrl || is_shift); - - if(!cs.IsAccepted() && !state_change) - return; - - if(cs || state_change) - { - moveCol = curpos.x; - moveRow = curpos.y; - - if(keyflags & K_CTRL) - { - bool select = true; - if(!select_row) - ClearSelection(); - else if(!multi_select) - select = false; - - if(select) - { - if(IsValidCursor(oldcur) && selected_items == 0 && cs.IsNew()) - { - shiftpos = oldcur; - - if(select_row) - { - SelectRange(oldcur, oldcur, true, true); - SelectRange(curpos, curpos, true, true); - } - else - { - SelectRange(oldcur, curpos, true, false); - } - } - else - { - shiftpos = curpos; - bool rowsel = vitems[curpos.y].IsSelect(); - SelectRange(curpos, curpos, !rowsel, select_row); - } - selecting = true; - } - } - else if(keyflags & K_SHIFT) - { - DoShiftSelect(); - selecting = true; - } - } - - #ifdef LOG_CALLBACKS - //LGR(2, "WhenLeftClick()"); - #endif - - WhenLeftClick(); - - if(editing && one_click_edit && cs.IsValid() ) //&& IsRowEditable() ? - StartEdit(); - else - RebuildToolBar(); -} - -void GridCtrl::LeftUp(Point p, dword keyflags) -{ - LG(0, "LeftUp"); - - ReleaseCapture(); - fixed_click = false; - - UpdateHighlighting(resizing ? GS_MOVE : GS_UP, p); - - if(moving_header) - { - LG(0, "moving_header"); - pophdr.Close(); - - moving_header = false; - if(fixed_top_click) - MoveCol(moveCol, curSplitCol); - else - MoveRow(moveRow, curSplitRow); - - if(focused_ctrl) - focused_ctrl->SetFocus(); - - fixed_top_click = false; - fixed_left_click = false; - - return; - } - - if(resizing) - { - Split(GS_UP); - resizeCol = resizeRow = resizing = false; - return; - } - - if(fixed_top_click && sorting && Distance(leftpnt, p) < 3) - { - int i = GetMouseRow(leftpnt, false, true); - int j = GetMouseCol(leftpnt, true, false); - - if(j >= fixed_cols && i == 0 && hitems[i].sortable) - { - int newSortCol = hitems[j].id; - - if(sorting_multicol && (keyflags & K_CTRL)) - { - int colidx = InMultisort(newSortCol); - - if(colidx < 0) - sortOrder.Add(newSortCol); - - int cnt = sortOrder.GetCount(); - - hitems[j].ChangeSortMode(newSortCol == sortOrder[cnt - 1]); - - if(colidx >= 0) - { - if(hitems[j].sortmode == 0) - { - sortOrder.Remove(colidx); - cnt--; - } - - if(WhenSort) - WhenSort(); - else - { - if(hitems[j].sortmode > 0 && colidx == cnt - 1) - GSort(); - else - Multisort(); - } - } - else - { - hitems[j].sortcol = cnt; - if(WhenSort) - WhenSort(); - else - GSort(); - } - } - else - { - if(sortCol >= 0 && sortCol != newSortCol) - { - int idx = GetIdCol(sortCol, true); - hitems[idx].sortmode = 0; - } - - ClearMultisort(1); - hitems[j].ChangeSortMode(); - hitems[j].sortcol = 1; - - if(hitems[j].sortmode == 0) - sortCol = -1; - else - sortCol = newSortCol; - - sortOrder.Add(newSortCol); - - if(WhenSort) - WhenSort(); - else - GSort(newSortCol, hitems[j].sortmode, fixed_rows); - } - - UpdateCursor(); - Repaint(false, true); - - if(WhenSorted) - WhenSorted(); - } - } - - if(moving_body) - { - popup.Close(); - moving_body = false; - MoveRows(curSplitRow + 1, !vitems[curpos.y].IsSelect()); - return; - } - - if(selected_rows > 0 && !selecting) - ClearSelection(); -} - -void GridCtrl::LeftDouble(Point p, dword keyflags) -{ - LG(0, "LeftDouble"); - - if(full_col_resizing && curSplitCol >= 0) - return; - - if(full_row_resizing && curSplitRow >= 0) - return; - - if(IsEmpty() || !IsMouseBody(p) || IsReadOnly()) - return; - - if(keyflags & K_SHIFT || keyflags & K_CTRL) - return; - - if(!valid_cursor) - return; - - if(editing) - StartEdit(); - - if(!IsCtrl(curpos)) - { - popup.Close(); - #ifdef LOG_CALLBACKS - LGR(2, "WhenLeftDouble()"); - #endif - WhenLeftDouble(); - } -} - -void GridCtrl::LeftRepeat(Point p, dword keyflags) -{ - if(!moving_header && !resizeCol && !resizeRow) - MouseAccel(p, resize_col_mode == 0, resize_row_mode == 0, keyflags); -} - -void GridCtrl::RightDown(Point p, dword keyflags) -{ - if(IsReadOnly()) - return; - - if(total_rows > fixed_rows) - { - if(!EndEdit()) - return; - - SetCursor0(p, CU_MOUSE); - } - - RebuildToolBar(); - SetFocus(); //jak nie bedzie menu to fokous zostanie na danym wierszu - MenuBar::Execute(WhenMenuBar); -} - void GridCtrl::Init() { bar.Set(WhenToolBar); @@ -3305,56 +2288,6 @@ GridCtrl::Item& GridCtrl::GetCell(int n, Id id) return items[vitems[n + fixed_rows].id][hitems[aliases.Get(id)].id]; } -int GridCtrl::GetMouseCol(Point &p, bool relative, bool fixed, bool full) -{ - if(!full && p.x < fixed_width) - return -1; - - int dx = 0; - - if(relative) - dx += sbx; - - int first_col = fixed ? 0 : max(firstVisCol, fixed_cols); - int last_col = max(lastVisCol, fixed_cols - 1); - - if(!fixed && last_col >= total_cols) - return -1; - - for(int i = first_col; i <= last_col; i++) - { - if(p.x >= hitems[i].nLeft(dx) && - p.x < hitems[i].nRight(dx)) - return i; - } - return -1; -} - -int GridCtrl::GetMouseRow(Point &p, bool relative, bool fixed, bool full) -{ - if(!full && p.y < fixed_height) - return -1; - - int dy = 0; - - if(relative) - dy += sby; - - int first_row = fixed ? 0 : max(firstVisRow, fixed_rows); - int last_row = max(lastVisRow, fixed_rows - 1); - - if(!fixed && last_row >= total_rows) - return -1; - - for(int i = first_row; i <= last_row; i++) - { - if(p.y >= vitems[i].nTop(dy) && - p.y < vitems[i].nBottom(dy)) - return i; - } - return -1; -} - void GridCtrl::MouseAccel(const Point &p, bool horz, bool vert, dword keyflags) { Size sz = GetSize(); @@ -4439,7 +3372,9 @@ void GridCtrl::RefreshRows(int from, int to, bool relative, bool fixed) from += fixed_rows; to += fixed_rows; } - Refresh(Rect(0, vitems[from].nTop(sby), GetSize().cx, vitems[to].nBottom(sby))); + if(vitems.GetCount()) + Refresh(Rect(0, vitems[clamp(from, 0, vitems.GetCount() - 1)].nTop(sby), GetSize().cx, + vitems[clamp(to, 0, vitems.GetCount() - 1)].nBottom(sby))); } void GridCtrl::RefreshFrom(int from) @@ -4533,7 +3468,6 @@ void GridCtrl::UpdateCursor() curpos.x = GetIdCol(curid.x); curpos.y = GetIdRow(curid.y); rowidx = curpos.y; - shiftpos = curpos; ctrlid.y = curpos.y < 0 ? -1 : curid.y; ctrlpos.y = curpos.y; rowfnd = curpos.y; @@ -5316,225 +4250,6 @@ bool GridCtrl::TabKey(bool enter_mode) return false; } -bool GridCtrl::Key(dword key, int) -{ - if(!IsReadOnly()) - switch(key) - { - case K_ENTER: - ClearSelection(); - WhenEnter(); - #ifdef LOG_CALLBACKS - LGR(2, "WhenEnter()"); - #endif - - if(enter_like_tab) - return TabKey(true); - else if(!SwitchEdit()) - return true; - /* - if(th.IsSorted()) - { - th.Multisort(); - Refresh(); - }*/ - - return true; - case K_ESCAPE: - { - bool quit = true; - if(search_string.GetCount() > 0) - { - ClearFound(); - quit = false; - } - else if(HasCtrls()) - { - bool canceled = CancelEdit(); - quit = !canceled; - } - if(quit) - { - WhenEscape(); - return false; - } - else - return true; - } - case K_SHIFT|K_LEFT: - GoLeft(); - DoShiftSelect(); - return true; - case K_SHIFT|K_RIGHT: - GoRight(); - DoShiftSelect(); - return true; - case K_SHIFT|K_UP: - GoPrev(); - DoShiftSelect(); - return true; - case K_SHIFT|K_DOWN: - GoNext(); - DoShiftSelect(); - return true; - case K_SHIFT|K_PAGEUP: - GoPageUp(); - DoShiftSelect(); - return true; - case K_SHIFT|K_PAGEDOWN: - GoPageDn(); - DoShiftSelect(); - return true; - case K_SHIFT_HOME: - GoBegin(); - DoShiftSelect(); - return true; - case K_SHIFT_END: - GoEnd(); - DoShiftSelect(); - return true; - case K_CTRL|K_LEFT: - GoLeft(); - DoCtrlSelect(); - return true; - case K_CTRL|K_RIGHT: - GoRight(); - DoCtrlSelect(); - return true; - case K_CTRL|K_UP: - if(select_row) - break; - GoPrev(); - DoCtrlSelect(); - return true; - case K_CTRL|K_DOWN: - if(select_row) - break; - GoNext(); - DoCtrlSelect(); - return true; - case K_UP: - GoPrev(); - ClearSelection(); - return true; - case K_DOWN: - GoNext(); - ClearSelection(); - return true; - case K_LEFT: - GoLeft(); - ClearSelection(); - return true; - case K_RIGHT: - GoRight(); - ClearSelection(); - return true; - - case K_HOME: - case K_CTRL_HOME: - case K_CTRL_PAGEUP: - GoBegin(); - ClearSelection(); - return true; - case K_END: - case K_CTRL_END: - case K_CTRL_PAGEDOWN: - GoEnd(); - ClearSelection(); - return true; - case K_PAGEUP: - GoPageUp(); - ClearSelection(); - return true; - case K_PAGEDOWN: - GoPageDn(); - ClearSelection(); - return true; - case K_TAB: - return TabKey(false); - case K_SHIFT|K_TAB: - if(HasCtrls()) - { - bool isprev = ShowPrevCtrl(); - return focused_ctrl ? true : isprev; - } - else if(tab_changes_row) - { - bool isprev = false; - if(select_row) - isprev = GoPrev(); - else - isprev = GoLeft(); - ClearSelection(); - - return isprev; - } - else - return false; - case K_CTRL|K_F: - if(searching) - { - find.SetFocus(); - return true; - } - else - return false; - case K_BACKSPACE: - { - if(searching) - { - int cnt = search_string.GetCount(); - if(cnt > 0) - { - search_string.Remove(cnt - 1); - find <<= search_string; - ShowMatchedRows(search_string); - } - return true; - } - else - return false; - } - case K_F3: - if(rowfnd >= 0) - { - for(int i = rowfnd + 1; i < total_rows; i++) - { - if(vitems[i].IsFound()) - { - rowfnd = i; - SetCursor0(i); - CenterCursor(); - WhenSearchCursor(); - return true; - } - } - for(int i = fixed_rows; i < rowfnd; i++) - { - if(vitems[i].IsFound()) - { - rowfnd = i; - SetCursor0(i); - CenterCursor(); - WhenSearchCursor(); - return true; - } - } - - return true; - } - return false; - case K_CTRL_W: - WriteClipboardText(GetColumnWidths()); - return true; - default: - if(searching && !isedit && Search(key)) - return true; - } - - return MenuBar::Scan(WhenMenuBar, key); -} - bool GridCtrl::Search(dword key) { //if(key & K_UP) @@ -5819,27 +4534,6 @@ void GridCtrl::SwapDown(int cnt) } } -void GridCtrl::MouseLeave() -{ - if(live_cursor) - { - LG(2, "MouseLeave:LiveCursor"); - SetCursor0(-1, -1, CU_HIGHLIGHT); - } - UpdateHighlighting(GS_BORDER, Point(0, 0)); - oldSplitCol = -1; - oldSplitRow = -1; - //popup.Close(); -} - -void GridCtrl::MouseWheel(Point p, int zdelta, dword keyflags) -{ - if(resize_row_mode == 0) - { - sby.Set(sby - zdelta / 4); - } -} - GridCtrl& GridCtrl::GridColor(Color fg) { fg_grid = fg; @@ -7135,287 +5829,6 @@ void GridCtrl::Duplicate(int i, int cnt) Duplicate0(fixed_rows + i, cnt); } -void GridCtrl::Select(int n, int cnt /* = 1*/) -{ - SelectCount(n + fixed_rows, cnt, true); -} - -void GridCtrl::SelectCount(int i, int cnt, bool sel) -{ - if(cnt <= 0) - return; - SelectRange(Point(fixed_cols, i), Point(total_cols - 1, i + cnt - 1), sel); -} - -void GridCtrl::SelectRange(int from, int to, bool sel) -{ - SelectRange(Point(fixed_cols, from), Point(total_cols - 1, to), sel); -} - -void GridCtrl::ShiftSelect(int from, int to) -{ - ShiftSelect(Point(fixed_cols, from), Point(total_cols - 1, to)); -} - -void GridCtrl::SelectRange(Point from, Point to, bool sel /* = true*/, bool fullrow /* = false*/) -{ - Point f, t; - - if(fullrow) - { - from.x = fixed_cols; - to.x = total_cols - 1; - } - - if(from.y < to.y) - { - f = from; - t = to; - } - else - { - f = to; - t = from; - } - - int ymin = f.y; - int ymax = t.y; - - int xmin = f.x; - int xmax = t.x; - - if(xmin > xmax) - { - int t = xmin; - xmin = xmax; - xmax = t; - } - - for(int i = ymin; i <= ymax; i++) - { - ItemRect &ir = vitems[i]; - int yid = ir.id; - - bool is_row_selected = false; - bool do_refresh = false; - - for(int j = fixed_cols; j < total_cols; j++) - { - int xid = hitems[j].id; - Item &it = items[yid][xid]; - - if(j >= xmin && j <= xmax) - { - if(it.IsSelect() != sel) - { - it.Select(sel); - do_refresh = true; - } - if(sel) - { - is_row_selected = true; - selected_items++; - } - else - selected_items--; - } - else if(it.IsSelect()) - is_row_selected = true; - } - - if(!ir.IsSelect()) - { - if(is_row_selected) - selected_rows++; - } - else if(!is_row_selected) - selected_rows--; - - ir.Select(is_row_selected); - - if(do_refresh) - RefreshRow(i, false, false); - - } -} - -void GridCtrl::SelectInverse(int from, int to) -{ - int nfrom = min(from, to); - int nto = max(from, to); - - for(int i = nfrom ; i <= nto; i++) - { - vitems[i].Select(!vitems[i].IsSelect()); - if(vitems[i].IsSelect()) - selected_rows++; - else - selected_rows--; - RefreshRow(i, 0); - } -} - -void GridCtrl::ShiftSelect(Point from, Point to) -{ - Point f, t; - - if(from.y < to.y) - { - f = from; - t = to; - } - else - { - f = to; - t = from; - } - - if(select_row) - { - f.x = fixed_cols; - t.x = total_cols; - } - - int ymin = f.y; - int ymax = t.y; - - int xmin = f.x; - int xmax = t.x; - - if(ymin == ymax && xmin > xmax) - { - int t = xmin; - xmin = xmax; - xmax = t; - } - - selected_rows = 0; - selected_items = 0; - - for(int i = fixed_rows; i < total_rows; i++) - { - ItemRect &ir = vitems[i]; - int yid = ir.id; - - bool is_row_selected = false; - bool do_refresh = false; - - if((i >= ymin && i <= ymax)) - { - for(int j = fixed_cols; j < total_cols; j++) - { - int xid = hitems[j].id; - - bool s = true; - if(i == ymin && ymin == ymax) - s = (j >= xmin && j <= xmax); - else if(i == ymin) s = (j >= xmin); - else if(i == ymax) s = (j <= xmax); - - if(items[yid][xid].IsSelect() != s) - { - items[yid][xid].Select(s); - do_refresh = true; - } - if(s) - { - is_row_selected = true; - selected_items++; - } - } - } - else - { - for(int j = fixed_cols; j < total_cols; j++) - if(items[yid][j].IsSelect()) - { - items[yid][j].Select(false); - do_refresh = true; - } - } - - if(is_row_selected) - selected_rows++; - - ir.Select(is_row_selected); - - if(do_refresh) - RefreshRow(i, false, false); - } -} - -void GridCtrl::DoShiftSelect() -{ - if(!shiftmode) - { - if(!IsValidCursor(oldcur)) - return; - shiftpos = oldcur; - shiftmode = true; - ShiftSelect(oldcur, curpos); - } - else - ShiftSelect(shiftpos, curpos); -} - -void GridCtrl::DoCtrlSelect() -{ - if(!IsValidCursor(oldcur)) - return; - - if(shiftmode && !select_row) - { - ClearSelection(); - shiftpos = oldcur; - } - - if(!IsValidCursor(shiftpos)) - shiftpos = oldcur; - - SelectRange(shiftpos, oldcur, false, select_row); - SelectRange(shiftpos, curpos, true, select_row); -} - -bool GridCtrl::IsSelected(int n, bool relative) -{ - //int id = vitems[n + (relative ? fixed_rows : 0)].id; - int id = n + (relative ? fixed_rows : 0); - return vitems[id].IsSelect() || vitems[id].IsCursor(); -} - -bool GridCtrl::IsSelected(int n, int m, bool relative) -{ - int r = relative ? fixed_rows + n : n; - int c = relative ? fixed_cols + m : m; - Item &it = GetItem(r, c); - return it.IsSelect() || it.IsCursor(); -} - -bool GridCtrl::IsSelected() -{ - return IsSelected(rowidx, false); -} - -void GridCtrl::ClearSelection() -{ - LG(0, "Cleared %d", selected_rows); - shiftmode = false; - shiftpos = curpos; - if(selected_rows > 0) - { - for(int i = fixed_rows; i < total_rows; i++) - { - vitems[i].Select(0); - for(int j = fixed_cols; j < total_cols; j++) - items[i][j].Select(0); - } - - Refresh(); - selected_rows = 0; - selected_items = 0; - } -} - void GridCtrl::DoInsert0(bool edit, bool after) { if(!valid_cursor) @@ -7552,7 +5965,6 @@ void GridCtrl::DoRemove() curpos.y = -1; valid_cursor = false; SetCursor0(curpos.x < 0 ? firstVisCol : curpos.x, max(fixed_rows, min(total_rows - 1, y)), 0, 0, -1); - shiftpos = curpos; } } diff --git a/uppsrc/GridCtrl/GridCtrl.h b/uppsrc/GridCtrl/GridCtrl.h index 376cc829d..8d11592ec 100644 --- a/uppsrc/GridCtrl/GridCtrl.h +++ b/uppsrc/GridCtrl/GridCtrl.h @@ -949,7 +949,6 @@ class GridCtrl : public Ctrl bool isedit:1; int genr_ctrls; bool edit_ctrls:1; - bool shiftmode:1; bool recalc_cols; bool recalc_rows; bool cancel_update_cell:1; @@ -962,7 +961,6 @@ class GridCtrl : public Ctrl bool cancel_move:1; bool mouse_move:1; bool is_clipboard:1; - bool selecting:1; bool enabled:1; bool call_whenchangecol:1; @@ -1024,14 +1022,15 @@ class GridCtrl : public Ctrl /* Points */ + Point curpos; // cursor position + Point anchor; // selection anchor + Point oldpos; - Point curpos; Point oldcur; Point curid; Point livecur; Point ctrlpos; Point ctrlid; - Point shiftpos; Point leftpnt; Size osz; @@ -1389,6 +1388,7 @@ class GridCtrl : public Ctrl int GetMouseRow(Point &p, bool relative = true, bool fixed = false, bool full = true); int GetMouseCol(Point &p, bool relative = true, bool fixed = false, bool full = true); + Point GetPos(Point p); void UpdateCursor(); @@ -1547,8 +1547,6 @@ class GridCtrl : public Ctrl void DoSelectAll(); void DoSwapUp(); void DoSwapDown(); - void DoShiftSelect(); - void DoCtrlSelect(); void DoGoBegin(); void DoGoEnd(); void DoGoNext(); @@ -1713,6 +1711,7 @@ class GridCtrl : public Ctrl void SelectCount(int i, int cnt = 1, bool sel = true); void SelectRange(int from, int to, bool sel = true); void SelectRange(Point from, Point to, bool sel = true, bool fullrow = false); + void SelectRange(const Rect& r, bool sel , bool fullrow ); void ShiftSelect(int from, int to); void ShiftSelect(Point from, Point to); void SelectInverse(int from, int to); diff --git a/uppsrc/GridCtrl/GridCtrl.upp b/uppsrc/GridCtrl/GridCtrl.upp index 8c8546653..ba4daba4f 100644 --- a/uppsrc/GridCtrl/GridCtrl.upp +++ b/uppsrc/GridCtrl/GridCtrl.upp @@ -10,6 +10,10 @@ uses(GRIDSQL) Sql; file GridCtrl.h, GridCtrl.cpp, + GridKey.cpp, + GridSelect.cpp, + GridMouse.cpp, + GridPaint.cpp, GridDisplay.h, GridDisplay.cpp, GridText.cpp, diff --git a/uppsrc/GridCtrl/GridKey.cpp b/uppsrc/GridCtrl/GridKey.cpp new file mode 100644 index 000000000..e50c9f1e8 --- /dev/null +++ b/uppsrc/GridCtrl/GridKey.cpp @@ -0,0 +1,216 @@ +#include "GridCtrl.h" + +namespace Upp { + +bool GridCtrl::Key(dword key, int) +{ + auto NewAnchor = [&] { + ClearSelection(); + anchor = curpos; + }; + + auto NewSelection = [&] { + ClearSelection(); + if(IsValidCursor(anchor) && IsValidCursor(curpos)) + SelectRange(Rect(anchor, curpos), true, select_row); + Refresh(); + }; + + if(!IsReadOnly()) + switch(key) + { + case K_ENTER: + ClearSelection(); + WhenEnter(); + #ifdef LOG_CALLBACKS + LGR(2, "WhenEnter()"); + #endif + + if(enter_like_tab) + return TabKey(true); + else if(!SwitchEdit()) + return true; + /* + if(th.IsSorted()) + { + th.Multisort(); + Refresh(); + }*/ + NewAnchor(); + return true; + case K_ESCAPE: + { + bool quit = true; + if(search_string.GetCount() > 0) + { + ClearFound(); + quit = false; + } + else if(HasCtrls()) + { + bool canceled = CancelEdit(); + quit = !canceled; + } + if(quit) + { + WhenEscape(); + return false; + } + else + return true; + } + case K_SHIFT|K_LEFT: + GoLeft(); + NewSelection(); + return true; + case K_SHIFT|K_RIGHT: + GoRight(); + NewSelection(); + return true; + case K_SHIFT|K_UP: + GoPrev(); + NewSelection(); + return true; + case K_SHIFT|K_DOWN: + GoNext(); + NewSelection(); + return true; + case K_SHIFT|K_PAGEUP: + GoPageUp(); + NewSelection(); + return true; + case K_SHIFT|K_PAGEDOWN: + GoPageDn(); + NewSelection(); + return true; + case K_SHIFT_HOME: + GoBegin(); + NewSelection(); + return true; + case K_SHIFT_END: + GoEnd(); + NewSelection(); + return true; + case K_UP: + GoPrev(); + NewAnchor(); + return true; + case K_DOWN: + GoNext(); + NewAnchor(); + return true; + case K_LEFT: + GoLeft(); + NewAnchor(); + return true; + case K_RIGHT: + GoRight(); + NewAnchor(); + return true; + + case K_HOME: + case K_CTRL_HOME: + case K_CTRL_PAGEUP: + GoBegin(); + NewAnchor(); + return true; + case K_END: + case K_CTRL_END: + case K_CTRL_PAGEDOWN: + GoEnd(); + NewAnchor(); + return true; + case K_PAGEUP: + GoPageUp(); + NewAnchor(); + return true; + case K_PAGEDOWN: + GoPageDn(); + NewAnchor(); + return true; + case K_TAB: + return TabKey(false); + case K_SHIFT|K_TAB: + if(HasCtrls()) + { + bool isprev = ShowPrevCtrl(); + return focused_ctrl ? true : isprev; + } + else if(tab_changes_row) + { + bool isprev = false; + if(select_row) + isprev = GoPrev(); + else + isprev = GoLeft(); + ClearSelection(); + + return isprev; + } + else + return false; + case K_CTRL|K_F: + if(searching) + { + find.SetFocus(); + return true; + } + else + return false; + case K_BACKSPACE: + { + if(searching) + { + int cnt = search_string.GetCount(); + if(cnt > 0) + { + search_string.Remove(cnt - 1); + find <<= search_string; + ShowMatchedRows(search_string); + } + return true; + } + else + return false; + } + case K_F3: + if(rowfnd >= 0) + { + for(int i = rowfnd + 1; i < total_rows; i++) + { + if(vitems[i].IsFound()) + { + rowfnd = i; + SetCursor0(i); + CenterCursor(); + WhenSearchCursor(); + return true; + } + } + for(int i = fixed_rows; i < rowfnd; i++) + { + if(vitems[i].IsFound()) + { + rowfnd = i; + SetCursor0(i); + CenterCursor(); + WhenSearchCursor(); + return true; + } + } + + return true; + } + return false; + case K_CTRL_W: + WriteClipboardText(GetColumnWidths()); + return true; + default: + if(searching && !isedit && Search(key)) + return true; + } + + return MenuBar::Scan(WhenMenuBar, key); +} + +}; \ No newline at end of file diff --git a/uppsrc/GridCtrl/GridMouse.cpp b/uppsrc/GridCtrl/GridMouse.cpp new file mode 100644 index 000000000..037a13c1f --- /dev/null +++ b/uppsrc/GridCtrl/GridMouse.cpp @@ -0,0 +1,577 @@ +#include "GridCtrl.h" + +namespace Upp { + +int GridCtrl::GetMouseCol(Point &p, bool relative, bool fixed, bool full) +{ + if(!full && p.x < fixed_width) + return -1; + + int dx = 0; + + if(relative) + dx += sbx; + + int first_col = fixed ? 0 : max(firstVisCol, fixed_cols); + int last_col = max(lastVisCol, fixed_cols - 1); + + if(!fixed && last_col >= total_cols) + return -1; + + for(int i = first_col; i <= last_col; i++) + { + if(p.x >= hitems[i].nLeft(dx) && + p.x < hitems[i].nRight(dx)) + return i; + } + return -1; +} + +int GridCtrl::GetMouseRow(Point &p, bool relative, bool fixed, bool full) +{ + if(!full && p.y < fixed_height) + return -1; + + int dy = 0; + + if(relative) + dy += sby; + + int first_row = fixed ? 0 : max(firstVisRow, fixed_rows); + int last_row = max(lastVisRow, fixed_rows - 1); + + if(!fixed && last_row >= total_rows) + return -1; + + for(int i = first_row; i <= last_row; i++) + { + if(p.y >= vitems[i].nTop(dy) && + p.y < vitems[i].nBottom(dy)) + return i; + } + return -1; +} + +Point GridCtrl::GetPos(Point p) +{ + return Point(GetMouseCol(p, true, false), GetMouseRow(p, true, false)); +} + +void GridCtrl::LeftDown(Point p, dword keyflags) +{ + //popup.Close(); + SetCapture(); + leftpnt = p; + just_clicked = true; + + fixed_top_click = p.x >= fixed_width && p.y < fixed_height; + fixed_left_click = p.x < fixed_width && p.y >= fixed_height; + fixed_click = fixed_top_click || fixed_left_click; + top_click = p.y < fixed_height; + + resizing = curResizeCol || curResizeRow; + + if(resizing) + { + popup.Close(); + + splitCol = curSplitCol; + splitRow = curSplitRow; + resizeCol = curResizeCol; + resizeRow = curResizeRow; + + Split(GS_DOWN); + return; + } + else if(fixed_click) + { + moveCol = oldMoveCol = GetMouseCol(p, fixed_top_click, 1); + moveRow = oldMoveRow = GetMouseRow(p, fixed_left_click, 1); + return; + } + + SetFocus(); + + if(IsEmpty() || IsReadOnly()) + return; + + bool is_shift = keyflags & K_SHIFT; + bool is_ctrl = keyflags & K_CTRL; + + Point oldcur = curpos; + + CurState cs = SetCursor0(p, CU_MOUSE | CU_HIDECTRLS); + bool state_change = cs.IsValid() && !cs.IsNew() && (is_ctrl || is_shift); + + if(!cs.IsAccepted() && !state_change) + return; + + anchor = curpos; + + if(cs || state_change) { + moveCol = curpos.x; + moveRow = curpos.y; + + if(keyflags & K_CTRL) { + SelectRange(oldcur, oldcur, !IsSelected(curpos.y, curpos.y), select_row); + SelectRange(curpos, curpos, !IsSelected(curpos.y, curpos.y), select_row); + } + else { + ClearSelection(); + if((keyflags & K_SHIFT) && multi_select && IsValidCursor(oldcur)) { + SetCursor0(oldcur, CU_HIDECTRLS); + Refresh(); + } + } + } + + #ifdef LOG_CALLBACKS + //LGR(2, "WhenLeftClick()"); + #endif + + WhenLeftClick(); + + if(editing && one_click_edit && cs.IsValid() ) //&& IsRowEditable() ? + StartEdit(); + else + RebuildToolBar(); + + SetCapture(); +} + +void GridCtrl::MouseMove(Point p, dword keyflags) +{ + mouse_move = true; + + if(resizing) + { + int si, lp, mp, off; + RectItems *its; + static int sub = 0; + + if(resizeCol) + { + mp = p.x; + lp = leftpnt.x; + si = splitCol; + its = &hitems; + bool top = fixed_top_click || (!fixed_left_click && full_col_resizing); + off = top ? sbx : 0; + } + else + { + mp = p.y; + lp = leftpnt.y; + si = splitRow; + its = &vitems; + bool left = fixed_left_click || (!fixed_top_click && full_row_resizing); + off = left ? sby : 0; + } + + int right = (*its)[si].nRight(off); + + if(just_clicked) + { + sub = right - lp; + just_clicked = false; + } + + if(SetDiffItemSize(resizeCol, *its, si, mp - right + sub)) + { + Split(GS_MOVE); + } + + return; + } + else if(fixed_click) + { + if((fixed_top_click && !moving_cols) || + (fixed_left_click && !moving_rows) || + moveCol < 0 || moveRow < 0) + return; + + if(!moving_header) + { + int diffx = p.x - leftpnt.x; + int diffy = p.y - leftpnt.y; + if(abs(diffx) < 5 && abs(diffy) < 5) + return; + + p -= Point(diffx, diffy); + + moving_header = true; + int idx = hitems[moveCol].id; + int idy = vitems[moveRow].id; + pophdr.val = idy > 0 ? GetConvertedColumn(moveCol, items[idy][idx].val) : items[idy][idx].val; + + if(fixed_top_click) + { + pophdr.sortmode = hitems[moveCol].sortmode; + pophdr.sortcol = hitems[moveCol].sortcol; + pophdr.sortcnt = sortOrder.GetCount(); + + UpdateHighlighting(GS_POPUP, p); + } + else + { + pophdr.sortmode = 0; + pophdr.sortcol = -1; + pophdr.sortcnt = 0; + } + + dx = hitems[moveCol].nLeft(fixed_top_click ? sbx : 0) - p.x; + dy = vitems[moveRow].nTop(fixed_left_click ? sby : 0) - p.y; + } + + + Point pt = p + GetScreenRect().TopLeft() + GetBarOffset(); + + pophdr.display = display; + pophdr.chameleon = chameleon; + pophdr.PopUp(this, pt.x + dx, pt.y + dy, hitems[moveCol].nWidth(), vitems[moveRow].nHeight()); + + if(fixed_top_click && curSplitCol != oldMoveCol) + { + moving_allowed = CanMoveCol(moveCol, curSplitCol); + RefreshTop(); + //Refresh(oldMoveCol >= 0 ? hitems[oldMoveCol].nRight(sbx) : 0, 0, hitems[curSplitCol].nRight(sbx), fixed_height); + oldMoveCol = curSplitCol; + } + + if(fixed_left_click && curSplitRow != oldMoveRow) + { + Refresh(0, 0, fixed_width, fixed_height); + RefreshLeft(); + oldMoveRow = curSplitRow; + } + return; + } + + if(leftpnt != p && p.y < fixed_height) + { + UpdateHighlighting(GS_MOVE, p); + } + + if(live_cursor && popup.IsOpen()) + { + LG(2, "MouseMove:LiveCursor"); + if(IsMouseBody(p)) + SetCursor0(p, CU_MOUSE | CU_HIGHLIGHT); + else + SetCursor0(-1, -1, CU_HIGHLIGHT); + } + + if(HasCapture()) + { + if(!moving_body) + { + anchor = GetPos(p); + Refresh(); + return; + /* if(keyflags & K_SHIFT) + { + if(SetCursor0(p, CU_MOUSE)) + DoShiftSelect(); + return; + } + + bool select = true; + if(select_row && !multi_select) + select = false; + + if(select && (keyflags & K_CTRL)) + { + if(SetCursor0(p, CU_MOUSE)) +// DoCtrlSelect(); + return; + }*/ + } + + if(moveCol < 0 || moveRow < 0) + return; + + if(!dragging) + return; + + if(!moving_body) + { + popup.Close(); + + if(!top_click && valid_cursor && + p.x < total_width && + p.y < total_height && + (abs(p.y - leftpnt.y) > 5 || + abs(p.x - leftpnt.x) > 5)) + moving_body = true; + + oldMoveRow = -1; + } + else + { + Point pt = p + GetScreenRect().TopLeft(); + + int row = curSplitRow - fixed_rows + 2; + if(select_row) + { + int count = max(1, selected_rows); + + if(vitems[curpos.y].IsSelect()) + popup.val = Format(t_("Moving selection (%d %s) before row %d"), count, count == 1 ? t_("row") : t_("rows"), row); + else + popup.val = Format(t_("Moving row %d before row %d"), curpos.y - fixed_rows + 1, row); + } + else + { + int count = max(1, selected_items); + popup.val = Format(t_("Moving %d %s before row %d"), count, count == 1 ? t_("cell") : t_("cells"), row); + } + + int px = pt.x + 15; + int py = pt.y + GD_ROW_HEIGHT; + + popup.gd = display; + popup.gd->row = 0; + popup.gd->col = 0; + popup.fg = SColorText; + popup.bg = SColorPaper; + popup.fnt = StdFont(); + popup.style = 0; + popup.PopUp(this, px, py, GetTextSize((String) popup.val, StdFont()).cx + 10, GD_ROW_HEIGHT); + SetFocus(); + + if(curSplitRow != oldMoveRow || scrollLeftRight) + { + int dy = sby; + if(oldMoveRow >= 0) + Refresh(Rect(0, vitems[oldMoveRow].nBottom(dy) - 5, GetSize().cx, vitems[oldMoveRow].nBottom(dy) + 5)); + else + Refresh(Rect(0, 0, GetSize().cx, 5)); + if(curSplitRow >= 0) + Refresh(Rect(0, vitems[curSplitRow].nBottom(dy) - 5, GetSize().cx, vitems[curSplitRow].nBottom(dy) + 5)); + else + Refresh(Rect(0, 0, GetSize().cx, 5)); + + oldMoveRow = curSplitRow; + popup.Refresh(); + + scrollLeftRight = false; + } + } + } + else + SyncPopup(); +} + +void GridCtrl::LeftUp(Point p, dword keyflags) +{ + LG(0, "LeftUp"); + + bool capture = HasCapture(); + + ReleaseCapture(); + Refresh(); + + fixed_click = false; + + UpdateHighlighting(resizing ? GS_MOVE : GS_UP, p); + + if(moving_header) + { + LG(0, "moving_header"); + pophdr.Close(); + + moving_header = false; + if(fixed_top_click) + MoveCol(moveCol, curSplitCol); + else + MoveRow(moveRow, curSplitRow); + + if(focused_ctrl) + focused_ctrl->SetFocus(); + + fixed_top_click = false; + fixed_left_click = false; + + return; + } + + if(resizing) + { + Split(GS_UP); + resizeCol = resizeRow = resizing = false; + return; + } + + if(fixed_top_click && sorting && Distance(leftpnt, p) < 3) + { + int i = GetMouseRow(leftpnt, false, true); + int j = GetMouseCol(leftpnt, true, false); + + if(j >= fixed_cols && i == 0 && hitems[i].sortable) + { + int newSortCol = hitems[j].id; + + if(sorting_multicol && (keyflags & K_CTRL)) + { + int colidx = InMultisort(newSortCol); + + if(colidx < 0) + sortOrder.Add(newSortCol); + + int cnt = sortOrder.GetCount(); + + hitems[j].ChangeSortMode(newSortCol == sortOrder[cnt - 1]); + + if(colidx >= 0) + { + if(hitems[j].sortmode == 0) + { + sortOrder.Remove(colidx); + cnt--; + } + + if(WhenSort) + WhenSort(); + else + { + if(hitems[j].sortmode > 0 && colidx == cnt - 1) + GSort(); + else + Multisort(); + } + } + else + { + hitems[j].sortcol = cnt; + if(WhenSort) + WhenSort(); + else + GSort(); + } + } + else + { + if(sortCol >= 0 && sortCol != newSortCol) + { + int idx = GetIdCol(sortCol, true); + hitems[idx].sortmode = 0; + } + + ClearMultisort(1); + hitems[j].ChangeSortMode(); + hitems[j].sortcol = 1; + + if(hitems[j].sortmode == 0) + sortCol = -1; + else + sortCol = newSortCol; + + sortOrder.Add(newSortCol); + + if(WhenSort) + WhenSort(); + else + GSort(newSortCol, hitems[j].sortmode, fixed_rows); + } + + UpdateCursor(); + Repaint(false, true); + + if(WhenSorted) + WhenSorted(); + } + } + + if(moving_body) + { + popup.Close(); + moving_body = false; + MoveRows(curSplitRow + 1, !vitems[curpos.y].IsSelect()); + return; + } + + if(IsValidCursor(anchor) && IsValidCursor(curpos)) + SelectRange(Rect(anchor, curpos), true, select_row); + + anchor = curpos; +} + +void GridCtrl::LeftDouble(Point p, dword keyflags) +{ + LG(0, "LeftDouble"); + + if(full_col_resizing && curSplitCol >= 0) + return; + + if(full_row_resizing && curSplitRow >= 0) + return; + + if(IsEmpty() || !IsMouseBody(p) || IsReadOnly()) + return; + + if(keyflags & K_SHIFT || keyflags & K_CTRL) + return; + + if(!valid_cursor) + return; + + if(editing) + StartEdit(); + + if(!IsCtrl(curpos)) + { + popup.Close(); + #ifdef LOG_CALLBACKS + LGR(2, "WhenLeftDouble()"); + #endif + WhenLeftDouble(); + } +} + +void GridCtrl::LeftRepeat(Point p, dword keyflags) +{ + if(!moving_header && !resizeCol && !resizeRow) + MouseAccel(p, resize_col_mode == 0, resize_row_mode == 0, keyflags); +} + +void GridCtrl::RightDown(Point p, dword keyflags) +{ + if(IsReadOnly()) + return; + + if(total_rows > fixed_rows) + { + if(!EndEdit()) + return; + + SetCursor0(p, CU_MOUSE); + } + + RebuildToolBar(); + SetFocus(); //jak nie bedzie menu to fokous zostanie na danym wierszu + MenuBar::Execute(WhenMenuBar); + anchor = curpos; +} + +void GridCtrl::MouseLeave() +{ + if(live_cursor) + { + LG(2, "MouseLeave:LiveCursor"); + SetCursor0(-1, -1, CU_HIGHLIGHT); + } + UpdateHighlighting(GS_BORDER, Point(0, 0)); + oldSplitCol = -1; + oldSplitRow = -1; + //popup.Close(); +} + +void GridCtrl::MouseWheel(Point p, int zdelta, dword keyflags) +{ + if(resize_row_mode == 0) + { + sby.Set(sby - zdelta / 4); + } +} + +}; \ No newline at end of file diff --git a/uppsrc/GridCtrl/GridPaint.cpp b/uppsrc/GridCtrl/GridPaint.cpp new file mode 100644 index 000000000..e66fa2d29 --- /dev/null +++ b/uppsrc/GridCtrl/GridPaint.cpp @@ -0,0 +1,513 @@ +#include "GridCtrl.h" + +namespace Upp { + +void GridCtrl::Paint(Draw &w) +{ + static int paintcnt = 0; + + Font stdfont(StdFont()); + + Size sz = GetSize(); + Rect rc = Rect(sz); //w.GetClip() - it always returns view rect now. bug?? + + if(!ready) + { + w.DrawRect(rc, SColorPaper); + return; + } + + int i, j, cx, cy, x, y; + bool skip; + Rect r; + + LG(0, "---- Paint(%d)", ++paintcnt); + + if(total_cols <= 1 || total_rows == 0) + { + LG(0, "---- Paint(%d) Empty.", paintcnt); + w.DrawRect(sz, SColorPaper); + return; + } + + if(UpdateCols() || UpdateRows()) + UpdateSizes(); + + if(firstCol < 0) firstCol = GetFirstVisCol(fixed_width); + if(firstRow < 0) firstRow = GetFirstVisRow(fixed_height); + + LG(0, "firstCol %d", firstCol); + LG(0, "firstRow %d", firstRow); + + int en = IsShowEnabled() ? 0 : GD::READONLY; + + //--------------------------------------------------------------------------------------- + + if(fixed_width > 0 && fixed_height > 0) + { + w.Clip(0, 0, fixed_width, fixed_height); + dword style = chameleon ? GD::CHAMELEON : 0; + + display->PaintFixed(w, 1, 1, 0, 0, fixed_width, fixed_height, + Value(""), + style, stdfont, false, false, + 0, -1, 0, + true); + w.End(); + } + + r.Set(fixed_width, 0, sz.cx, summary_row ? sz.cy : fixed_height); + + if(w.IsPainting(r) && total_cols > 1) + { + LG(0, "Top header"); + w.Clip(r); + + x = hitems[total_cols - 1].nRight(sbx); + int rx = x; + + int firstcol = indicator ? 0 : (fixed_cols > 1 ? 1 : firstVisCol); + if(firstCol < 0) firstCol = 0; + int jfc = chameleon ? 0 : firstCol; + + for(i = 0; i < fixed_rows; i++) + { + for(j = jfc; j < total_cols; j++) + { + ItemRect& hi = hitems[j]; + + if(hi.hidden) + continue; + + int jj = j; + Item &it = GetItemSize(i, j, x, y, cx, cy, skip, true, false); + if(skip) + continue; + + if(x >= rc.right) + break; + + if(w.IsPainting(x, y, cx, cy)) + { + GridDisplay * gd = it.display ? it.display : display; + + dword style = hi.style | hi.halign; + if(i > 0) style &= ~GD::HIGHLIGHT; + if(chameleon) + style |= GD::CHAMELEON; + + Font fnt(stdfont); + gd->SetLeftImage(hi.img); + gd->ReverseSortIcon(reverse_sort_icon); + gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, + i == 0 ? it.val : GetConvertedColumn(hi.id, it.val), + style | en, IsNull(hi.hfnt) ? fnt : hi.hfnt, false, false, + i == 0 ? hi.sortmode : 0, + hi.sortcol, + sortOrder.GetCount(), + true); + + it.rcx = gd->real_size.cx; + it.rcy = gd->real_size.cy; + } + + if(summary_row && i == 0) + { + cy = GD_HDR_HEIGHT; + y = sz.cy - cy; + + if(w.IsPainting(x, y, cx, cy)) + { + Item &it = summary[hi.id]; + GridDisplay * gd = it.display ? it.display : display; + + dword style = en | hi.halign; + if(chameleon) + style |= GD::CHAMELEON; + + String s; + if(hi.sop != SOP_NONE && !hi.sopfrm.IsEmpty() && !IsNull(it.val)) + s = Format(hi.sopfrm, it.val); + else + s = IsString(it.val) ? it.val : StdConvert().Format(it.val); + gd->SetLeftImage(Null); + //gd->PaintFixed(w, jj == firstcol, i == 0, x, y, cx, cy, s, + // style | en, stdfont, false, false, 0, -1, 0, true); + Color fg = Black; + Color bg = Blend(Blue, White, 240); + w.DrawRect(x, y, cx, 1, Gray); + Font fnt(stdfont); + + if(style & GD::READONLY) + { + bg = Blend(bg, SGray(), 40); + fg = Blend(fg, SGray(), 200); + } + + gd->Paint(w, x, y + 1, cx, cy - 1, s, style, fg, bg, fnt.Bold(), false, 0, 0); + + it.rcx = gd->real_size.cx; + it.rcy = gd->real_size.cy; + } + } + } + } + if(rx < sz.cx || chameleon) + { + int cx = sz.cx - rx + 1; + dword style = 0; + if(chameleon) + { + cx = max(10, cx); + style = GD::CHAMELEON; + } + display->PaintFixed(w, 0, 1, rx, 0, cx, fixed_height, + Value(""), + style, stdfont, false, false, + 0, -1, 0, + true); + if(summary_row) + { + Color fg = Black; + Color bg = Blend(Blue, White, 240); + w.DrawRect(rx, y, cx, 1, Gray); + + if(style & GD::READONLY) + { + bg = Blend(bg, SGray(), 40); + fg = Blend(fg, SGray(), 200); + } + display->Paint(w, rx, y + 1, cx, GD_HDR_HEIGHT - 1, Value(""), style, fg, bg, stdfont, false, 0, 0); + } + } + + w.End(); + } + //--------------------------------------------------------------------------------------- + + bool can_paint = firstCol >= 0 && firstRow >= 0; + r.Set(0, fixed_height, fixed_width, sz.cy); + + if(can_paint && w.IsPainting(r)) + { + LG(0, "Left header"); + w.Clip(r); + y = vitems[total_rows - 1].nBottom(sby); + + if(y < sz.cy) + w.DrawRect(Rect(0, y, fixed_width, sz.cy - summary_height), SColorPaper); + + for(i = 0; i < fixed_cols; i++) + { + bool firstx = (i == !indicator); + bool indicator = (i == 0); + int id = hitems[i].id; + + for(j = firstRow; j < total_rows; j++) + { + ItemRect& vi = vitems[j]; + + if(vi.hidden) + continue; + + Item &it = GetItemSize(j, i, x, y, cx, cy, skip, false, true); + + if(skip) + continue; + + if(y >= rc.bottom) + break; + + if(w.IsPainting(x, y, cx, cy)) + { + GridDisplay * gd = it.display ? it.display : display; + + dword style = vi.style; + if(i > 0) style &= ~GD::HIGHLIGHT; + if(chameleon) + style |= GD::CHAMELEON; + + Font fnt(stdfont); + gd->PaintFixed(w, firstx, j == 0, x, y, cx, cy, + GetConvertedColumn(id, it.val), + style | en, IsNull(vi.hfnt) ? fnt : vi.hfnt, + indicator, false, 0, -1, 0, false); + + it.rcx = gd->real_size.cx; + it.rcy = gd->real_size.cy; + } + } + + if(summary_row) + { + j = 0; + cy = GD_HDR_HEIGHT; + y = sz.cy - cy; + if(w.IsPainting(x, y, cx, cy)) + { + Item& it = summary[hitems[i].id]; + GridDisplay * gd = it.display ? it.display : display; + + dword style = vitems[j].style; + if(chameleon) + style |= GD::CHAMELEON; + +// gd->PaintFixed(w, firstx, true, x, y, cx, cy, +// GetConvertedColumn(id, it.val), +// style | en, stdfont, +// false, false, 0, -1, 0, false); +// + Color fg = Black; + Color bg = Blend(Blue, White, 240); + w.DrawRect(x, y, cx, 1, Gray); + Font fnt(stdfont); + gd->Paint(w, x, y + 1, cx, cy - 1, GetConvertedColumn(id, it.val), style | en, fg, bg, fnt.Bold(), false, 0, 0); + + } + } + } + + w.End(); + } + + //--------------------------------------------------------------------------------------- + // Draw the "active" (non-fixed) cells: + + r.Set(fixed_width, fixed_height, sz.cx, sz.cy - summary_height); + + if(can_paint && w.IsPainting(r)) + { + LG(0, "Body"); + w.Clip(r); + + x = hitems[total_cols - 1].nRight(sbx); + y = vitems[total_rows - 1].nBottom(sby); + + if(x < sz.cx) w.DrawRect(Rect(max(x, rc.left), max(fixed_height, rc.top), sz.cx, sz.cy), SColorPaper); + if(y < sz.cy) w.DrawRect(Rect(max(fixed_width, rc.left), max(y, rc.top), sz.cx, sz.cy), SColorPaper); + + bool hasfocus = HasFocus() || holder.HasFocusDeep(); + + for(i = max(firstRow, fixed_rows); i < total_rows; i++) + { + ItemRect& vi = vitems[i]; + if(vi.hidden) continue; + + bool even = coloring_mode == 2 ? (i - vi.n - fixed_rows) & 1 : false; + + for(j = max(firstCol, fixed_cols); j < total_cols; j++) + { + const ItemRect& hi = hitems[j]; + + if(hi.hidden) + continue; + + Item &it = GetItemSize(i, j, x, y, cx, cy, skip); + if(skip) + continue; + + if(y >= rc.bottom) + goto end_paint; + + if(x >= rc.right) + break; + + if(!w.IsPainting(0, y, sz.cx, cy)) + break; + + if(w.IsPainting(x, y, cx, cy)) + { + bool iscur = draw_focus ? (i == curpos.y && j == curpos.x) : false; + + if(coloring_mode == 1) + even = (j - hi.n - fixed_cols) & 1; + + int id = hi.id; + + dword style = en | (select_row ? vi.style : it.style) | hi.balign; + dword istyle = it.style; + + if(hitems[j].wrap) + style |= GD::WRAP; + if(ctrlpos.y == i && edits[id].ctrl && edits[id].ctrl->IsShown()) + style |= GD::NOTEXT; + if(it.ctrl) + style |= GD::NOTEXT; + + if(coloring_mode > 0) + style |= (even ? GD::EVEN : GD::ODD); + if(hasfocus) + style |= GD::FOCUS; + + if(IsValidCursor(anchor) && anchor != curpos) { // mouse selection in progress + Rect r(anchor, curpos); + r.Normalize(); + r.SetSize(r.GetSize() + 1); + if(r.Contains(Point(j, i))) + style |= GD::SELECT; + } + + Color cfg; + Color cbg; + + Font fnt = StdFont(); + GridDisplay* gd; + Value val = GetItemValue(it, id, hi, vi); + GetItemAttrs(it, val, i, j, vi, hi, style, gd, cfg, cbg, fnt); + + Color fg = SColorText; + Color bg = SColorPaper; + + bool custom = true; + + if(style & GD::CURSOR) + { + if(style & GD::FOCUS) + { + fg = iscur ? Blend(bg_focus, Black, 230) : fg_focus; + bg = iscur ? Blend(bg_focus, White, 230) : bg_focus; + } + else + { + bg = Blend(SColorDisabled, bg); + } + custom = false; + } + else if(style & GD::LIVE) + { + fg = fg_live; + bg = bg_live; + custom = false; + } + else if(istyle & GD::FOUND) + { + fg = fg_found; + bg = bg_found; + custom = false; + } + else if(style & GD::SELECT) + { + fg = fg_select; + bg = bg_select; + custom = false; + } + else if(style & GD::EVEN) + { + fg = fg_even; + bg = bg_even; + } + else if(style & GD::ODD) + { + fg = fg_odd; + bg = bg_odd; + } + + if(custom) + { + if(!IsNull(cfg)) fg = cfg; + if(!IsNull(cbg)) bg = cbg; + } + + if(style & GD::READONLY) + { + bg = Blend(bg, SGray(), 40); + fg = Blend(fg, SGray(), 200); + } + + gd->SetBgImage(vi.img); + gd->col = j - fixed_rows; + gd->row = i - fixed_cols; + gd->parent = this; + + val = GetAttrTextVal(val); + + gd->Paint(w, x, y, cx, cy, + val, style, + fg, bg, fnt, it.style & GD::FOUND, it.fs, it.fe); + + it.rcx = gd->real_size.cx; + it.rcy = gd->real_size.cy; + + if(vert_grid) + { + bool skip = false; + if(!draw_last_vert_line && j == total_cols - 1) + skip = true; + + if(!skip) + w.DrawRect(x + cx - 1, y, 1, cy, fg_grid); + } + if(horz_grid) + { + bool skip = false; + if(!draw_last_horz_line && i == total_rows - 1) + skip = true; + + if(!skip) + w.DrawRect(x, y + cy - 1, cx, 1, fg_grid); + } + + if(iscur && draw_focus) + Upp::DrawFocus(w, x, y, cx, cy); + } + } + } + + end_paint: + + w.End(); + + lastCol = j - 1; + lastRow = i - 1; + } + + + if(moving_header && fixed_top_click && curSplitCol >= 0) + { + r.Set(fixed_width, 0, sz.cx, fixed_height); + w.Clip(r); + bool lastcol = curSplitCol == lastVisCol; + + int cp = curSplitCol; + if(!lastcol) + while(++cp < total_cols && hitems[cp].hidden); + + int cx = hitems[cp].nWidth() / 2; + int x = lastcol ? hitems[curSplitCol].nLeft(sbx) + cx + : hitems[curSplitCol].nRight(sbx) - 1; + DrawFatFrame(w, x, 0, cx, vitems[fixed_rows - 1].nBottom(), moving_allowed ? LtBlue : Red, 2); + w.End(); + } + + if(moving_header && fixed_left_click) + { + int dy = curSplitRow == lastVisRow ? -2 : -1; + int y = curSplitRow >= 0 ? vitems[curSplitRow].nBottom(sby) + dy : 0; + if(y >= fixed_height - 1) + DrawVertDragLine(w, y, hitems[fixed_cols - 1].nRight(), 0, moving_allowed ? LtBlue : Red); + } + + if(moving_body) + { + int dy = curSplitRow == lastVisRow ? -2 : -1; + int y = curSplitRow >= 0 ? vitems[curSplitRow].nBottom(sby) + dy : 0; + if(y >= fixed_height - 1) + DrawVertDragLine(w, y, sz.cx, fixed_width - 1, LtBlue); + } + + if(search_display && !search_string.IsEmpty()) + { + Size tsz = GetTextSize(search_string, StdFont()); + w.DrawRect(Rect(0, sz.cy - tsz.cy - 4, tsz.cx + 4, sz.cy), SRed); + w.DrawText(2, sz.cy - tsz.cy - 2, search_string, StdFont(), SYellow); + } + + if(!can_paint) + w.DrawRect(Rect(0, total_cols > 1 ? fixed_height : 0, sz.cx, sz.cy), SColorPaper); + if(++paint_flag > 100) + paint_flag = 0; + + LG(0, "---- Paint(%d).", paintcnt); +} + +}; \ No newline at end of file diff --git a/uppsrc/GridCtrl/GridSelect.cpp b/uppsrc/GridCtrl/GridSelect.cpp new file mode 100644 index 000000000..fbe8c1ff3 --- /dev/null +++ b/uppsrc/GridCtrl/GridSelect.cpp @@ -0,0 +1,258 @@ +#include "GridCtrl.h" + +namespace Upp { + +void GridCtrl::Select(int n, int cnt /* = 1*/) +{ + SelectCount(n + fixed_rows, cnt, true); +} + +void GridCtrl::SelectCount(int i, int cnt, bool sel) +{ + if(cnt <= 0) + return; + SelectRange(Point(fixed_cols, i), Point(total_cols - 1, i + cnt - 1), sel); +} + +void GridCtrl::SelectRange(int from, int to, bool sel) +{ + SelectRange(Point(fixed_cols, from), Point(total_cols - 1, to), sel); +} + +void GridCtrl::ShiftSelect(int from, int to) +{ + ShiftSelect(Point(fixed_cols, from), Point(total_cols - 1, to)); +} + +void GridCtrl::SelectRange(Point from, Point to, bool sel /* = true*/, bool fullrow /* = false*/) +{ + Point f, t; + + if(fullrow) + { + from.x = fixed_cols; + to.x = total_cols - 1; + } + + if(from.y < to.y) + { + f = from; + t = to; + } + else + { + f = to; + t = from; + } + + int ymin = f.y; + int ymax = t.y; + + int xmin = f.x; + int xmax = t.x; + + if(xmin > xmax) + { + int t = xmin; + xmin = xmax; + xmax = t; + } + + for(int i = ymin; i <= ymax; i++) + { + ItemRect &ir = vitems[i]; + int yid = ir.id; + + bool is_row_selected = false; + bool do_refresh = false; + + for(int j = fixed_cols; j < total_cols; j++) + { + int xid = hitems[j].id; + Item &it = items[yid][xid]; + + if(j >= xmin && j <= xmax) + { + if(it.IsSelect() != sel) + { + it.Select(sel); + do_refresh = true; + } + if(sel) + { + is_row_selected = true; + selected_items++; + } + else + selected_items--; + } + else if(it.IsSelect()) + is_row_selected = true; + } + + if(!ir.IsSelect()) + { + if(is_row_selected) + selected_rows++; + } + else if(!is_row_selected) + selected_rows--; + + ir.Select(is_row_selected); + + if(do_refresh) + RefreshRow(i, false, false); + + } +} + +void GridCtrl::SelectInverse(int from, int to) +{ + int nfrom = min(from, to); + int nto = max(from, to); + + for(int i = nfrom ; i <= nto; i++) + { + vitems[i].Select(!vitems[i].IsSelect()); + if(vitems[i].IsSelect()) + selected_rows++; + else + selected_rows--; + RefreshRow(i, 0); + } +} + +void GridCtrl::ShiftSelect(Point from, Point to) +{ + Point f, t; + + if(from.y < to.y) + { + f = from; + t = to; + } + else + { + f = to; + t = from; + } + + if(select_row) + { + f.x = fixed_cols; + t.x = total_cols; + } + + int ymin = f.y; + int ymax = t.y; + + int xmin = f.x; + int xmax = t.x; + + if(ymin == ymax && xmin > xmax) + { + int t = xmin; + xmin = xmax; + xmax = t; + } + + selected_rows = 0; + selected_items = 0; + + for(int i = fixed_rows; i < total_rows; i++) + { + ItemRect &ir = vitems[i]; + int yid = ir.id; + + bool is_row_selected = false; + bool do_refresh = false; + + if((i >= ymin && i <= ymax)) + { + for(int j = fixed_cols; j < total_cols; j++) + { + int xid = hitems[j].id; + + bool s = true; + if(i == ymin && ymin == ymax) + s = (j >= xmin && j <= xmax); + else if(i == ymin) s = (j >= xmin); + else if(i == ymax) s = (j <= xmax); + + if(items[yid][xid].IsSelect() != s) + { + items[yid][xid].Select(s); + do_refresh = true; + } + if(s) + { + is_row_selected = true; + selected_items++; + } + } + } + else + { + for(int j = fixed_cols; j < total_cols; j++) + if(items[yid][j].IsSelect()) + { + items[yid][j].Select(false); + do_refresh = true; + } + } + + if(is_row_selected) + selected_rows++; + + ir.Select(is_row_selected); + + if(do_refresh) + RefreshRow(i, false, false); + } +} + +void GridCtrl::SelectRange(const Rect& r, bool sel /* = true*/, bool fullrow /* = false*/) +{ + Rect rr = r.Normalized(); + SelectRange(rr.TopLeft(), rr.BottomRight(), sel, fullrow); +} + +bool GridCtrl::IsSelected(int n, bool relative) +{ + //int id = vitems[n + (relative ? fixed_rows : 0)].id; + int id = n + (relative ? fixed_rows : 0); + return vitems[id].IsSelect() || vitems[id].IsCursor(); +} + +bool GridCtrl::IsSelected(int n, int m, bool relative) +{ + int r = relative ? fixed_rows + n : n; + int c = relative ? fixed_cols + m : m; + Item &it = GetItem(r, c); + return it.IsSelect() || it.IsCursor(); +} + +bool GridCtrl::IsSelected() +{ + return IsSelected(rowidx, false); +} + +void GridCtrl::ClearSelection() +{ + LG(0, "Cleared %d", selected_rows); + if(selected_rows > 0) + { + for(int i = fixed_rows; i < total_rows; i++) + { + vitems[i].Select(0); + for(int j = fixed_cols; j < total_cols; j++) + items[i][j].Select(0); + } + + Refresh(); + selected_rows = 0; + selected_items = 0; + } +} + +}; \ No newline at end of file diff --git a/uppsrc/ide/AutoSetup.cpp b/uppsrc/ide/AutoSetup.cpp index 5aacd6d1d..4efb71395 100644 --- a/uppsrc/ide/AutoSetup.cpp +++ b/uppsrc/ide/AutoSetup.cpp @@ -4,25 +4,11 @@ extern FileSel& sSD(); -static void sSetFolder(EditField *f) -{ - if(!sSD().ExecuteSelectDir()) return; - *f <<= ~sSD(); -} - -void DirSel(EditField& f, FrameRight