mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
ide: cosmetics, GridCtrl: Selection refactored to follow spreadsheet model
git-svn-id: svn://ultimatepp.org/upp/trunk@15558 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
77f3a86282
commit
a01614cb42
13 changed files with 1610 additions and 1626 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<BottomSeparatorFrameCls>(); }
|
||||
CtrlFrame& TopSeparatorFrame() { return Single<TopSeparatorFrameCls>(); }
|
||||
CtrlFrame& RightSeparatorFrame() { return Single<RightSeparatorFrameCls>(); }
|
||||
CtrlFrame& LeftSeparatorFrame() { return Single<LeftSeparatorFrameCls>(); }
|
||||
|
||||
CtrlFrame& RightGapFrame() { return Single<RightGapFrameCls>(); }
|
||||
|
||||
CH_INT(FrameButtonWidth, DPI(17));
|
||||
CH_INT(ScrollBarArrowSize, FrameButtonWidth());
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
216
uppsrc/GridCtrl/GridKey.cpp
Normal file
216
uppsrc/GridCtrl/GridKey.cpp
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
577
uppsrc/GridCtrl/GridMouse.cpp
Normal file
577
uppsrc/GridCtrl/GridMouse.cpp
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
513
uppsrc/GridCtrl/GridPaint.cpp
Normal file
513
uppsrc/GridCtrl/GridPaint.cpp
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
||||
};
|
||||
258
uppsrc/GridCtrl/GridSelect.cpp
Normal file
258
uppsrc/GridCtrl/GridSelect.cpp
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -4,25 +4,11 @@
|
|||
|
||||
extern FileSel& sSD();
|
||||
|
||||
static void sSetFolder(EditField *f)
|
||||
{
|
||||
if(!sSD().ExecuteSelectDir()) return;
|
||||
*f <<= ~sSD();
|
||||
}
|
||||
|
||||
void DirSel(EditField& f, FrameRight<Button>& b)
|
||||
{
|
||||
f.AddFrame(b);
|
||||
b <<= callback1(&sSetFolder, &f);
|
||||
b.SetImage(CtrlImg::smallright()).NoWantFocus();
|
||||
}
|
||||
|
||||
String NormalizePathNN(const String& path)
|
||||
{
|
||||
return IsNull(path) ? path : NormalizePath(path);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
bool ExistProgram(String& bin, const char *dir, const char *file)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,24 @@
|
|||
#define IMAGEFILE <ide/Common/common.iml>
|
||||
#include <Draw/iml_source.h>
|
||||
|
||||
void DirSelect(Ctrl& t, Button& b)
|
||||
{
|
||||
b.SetImage(CtrlImg::Dir());
|
||||
b << [&] {
|
||||
String s = SelectDirectory();
|
||||
if(s.GetCount())
|
||||
t <<= s;
|
||||
};
|
||||
}
|
||||
|
||||
void DirSel(EditField& f, FrameRight<Button>& b)
|
||||
{
|
||||
b.Width(DPI(20));
|
||||
f.InsertFrame(0, b);
|
||||
f.InsertFrame(1, RightGapFrame());
|
||||
DirSelect(f, b);
|
||||
}
|
||||
|
||||
void IdeFileIcon0(bool dir, const String& filename, Image& img)
|
||||
{
|
||||
if(dir) return;
|
||||
|
|
@ -233,13 +251,3 @@ void ShellOpenFolder(const String& dir)
|
|||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DirSelect(Ctrl& t, Button& b)
|
||||
{
|
||||
b.SetImage(CtrlImg::Dir());
|
||||
b << [&] {
|
||||
String s = SelectDirectory();
|
||||
if(s.GetCount())
|
||||
t <<= s;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ FileSel& AnyPackageFs();
|
|||
FileSel& BasedSourceFs();
|
||||
FileSel& OutputFs();
|
||||
|
||||
void DirSelect(Ctrl& t, Button& b);
|
||||
|
||||
void ShellOpenFolder(const String& dir);
|
||||
|
||||
Image ImageOver(const Image& back, const Image& over);
|
||||
|
|
|
|||
|
|
@ -306,6 +306,7 @@ void DlSpellerLangs(DropList& dl);
|
|||
|
||||
#include "Assist.h"
|
||||
|
||||
void DirSelect(Ctrl& t, Button& b);
|
||||
void DirSel(EditField& f, FrameRight<Button>& b);
|
||||
bool CopyFolder(const char *dst, const char *src, Progress *pi);
|
||||
void RepoSyncDirs(const Vector<String>& working);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue