VirtualButtons improvements

This commit is contained in:
Mirek Fidler 2022-04-26 13:13:27 +02:00
parent 5a711f77ae
commit 67f810e0f5
12 changed files with 307 additions and 127 deletions

View file

@ -20,9 +20,13 @@ GUI_APP_MAIN
RDUMP(sizeof(Label));
RDUMP(sizeof(EditField));
RDUMP(sizeof(EditString));
RDUMP(sizeof(EditInt));
RDUMP(sizeof(SpinButtons));
RDUMP(sizeof(EditIntSpin));
RDUMP(sizeof(EditDoubleSpin));
RDUMP(sizeof(DisplayPopup));
RDUMP(sizeof(PopUpTable));
RDUMP(sizeof(DropList));
RDUMP(sizeof(WithDropChoice<EditString>));
RDUMP(sizeof(ArrayCtrl));
RDUMP(sizeof(TreeCtrl));
RDUMP(sizeof(TreeCtrl::Node));

View file

@ -1,55 +1,55 @@
#include "CtrlLib.h"
namespace Upp {
Point DisplayPopup::Op(Point p)
Point DisplayPopup::PopUp::Op(Point p)
{
return p + GetScreenView().TopLeft() - ctrl->GetScreenView().TopLeft();
}
void DisplayPopup::LeftDown(Point p, dword flags)
void DisplayPopup::PopUp::LeftDown(Point p, dword flags)
{
if(ctrl) ctrl->LeftDown(Op(p), flags);
}
void DisplayPopup::LeftDrag(Point p, dword flags)
void DisplayPopup::PopUp::LeftDrag(Point p, dword flags)
{
if(ctrl) ctrl->LeftDrag(Op(p), flags);
}
void DisplayPopup::LeftDouble(Point p, dword flags)
void DisplayPopup::PopUp::LeftDouble(Point p, dword flags)
{
if(ctrl) ctrl->LeftDouble(Op(p), flags);
}
void DisplayPopup::RightDown(Point p, dword flags)
void DisplayPopup::PopUp::RightDown(Point p, dword flags)
{
if(ctrl) ctrl->RightDown(Op(p), flags);
}
void DisplayPopup::LeftUp(Point p, dword flags)
void DisplayPopup::PopUp::LeftUp(Point p, dword flags)
{
if(ctrl) ctrl->LeftUp(Op(p), flags);
}
void DisplayPopup::MouseWheel(Point p, int zdelta, dword flags)
void DisplayPopup::PopUp::MouseWheel(Point p, int zdelta, dword flags)
{
if(ctrl) ctrl->MouseWheel(Op(p), zdelta, flags);
}
void DisplayPopup::MouseLeave()
void DisplayPopup::PopUp::MouseLeave()
{
Cancel();
}
void DisplayPopup::MouseMove(Point p, dword flags)
void DisplayPopup::PopUp::MouseMove(Point p, dword flags)
{
p += GetScreenView().TopLeft();
if(!slim.Contains(p))
MouseLeave();
}
void DisplayPopup::Paint(Draw& w)
void DisplayPopup::PopUp::Paint(Draw& w)
{
Rect r = GetSize();
w.DrawRect(r, SColorPaper);
@ -62,13 +62,13 @@ void DisplayPopup::Paint(Draw& w)
}
}
Vector<DisplayPopup *>& DisplayPopup::all()
Vector<DisplayPopup::PopUp *>& DisplayPopup::PopUp::all()
{
static Vector<DisplayPopup *> all;
static Vector<DisplayPopup::PopUp *> all;
return all;
}
DisplayPopup::DisplayPopup()
DisplayPopup::PopUp::PopUp()
{
SetFrame(BlackFrame());
display = NULL;
@ -83,14 +83,14 @@ DisplayPopup::DisplayPopup()
all().Add(this);
}
DisplayPopup::~DisplayPopup()
DisplayPopup::PopUp::~PopUp()
{
int q = FindIndex(all(), this);
if(q >= 0)
all().Remove(q);
}
void DisplayPopup::Sync()
void DisplayPopup::PopUp::Sync()
{
if(!IsMainThread()) {
PostCallback(PTEBACK(Sync));
@ -144,20 +144,20 @@ void DisplayPopup::Sync()
}
}
if(IsOpen() && !GetDragAndDropSource())
Close();
WhenClose();
}
void DisplayPopup::SyncAll()
void DisplayPopup::PopUp::SyncAll()
{
int n = 0;
for(DisplayPopup *p : all())
for(DisplayPopup::PopUp *p : all())
if(p->ctrl && p->ctrl->IsOpen()) {
p->Sync();
n++;
}
}
bool DisplayPopup::StateHook(Ctrl *, int reason)
bool DisplayPopup::PopUp::StateHook(Ctrl *, int reason)
{
if(reason == FOCUS)
SyncAll();
@ -165,13 +165,13 @@ bool DisplayPopup::StateHook(Ctrl *, int reason)
}
bool DisplayPopup::MouseHook(Ctrl *, bool, int, Point, int, dword)
bool DisplayPopup::PopUp::MouseHook(Ctrl *, bool, int, Point, int, dword)
{
SyncAll();
return false;
}
void DisplayPopup::Cancel()
void DisplayPopup::PopUp::Cancel()
{
if(GetDragAndDropSource())
return;
@ -179,17 +179,17 @@ void DisplayPopup::Cancel()
Sync();
}
bool DisplayPopup::IsOpen()
bool DisplayPopup::PopUp::IsOpen()
{
return Ctrl::IsOpen();
}
bool DisplayPopup::HasMouse()
bool DisplayPopup::PopUp::HasMouse()
{
return Ctrl::HasMouse() || ctrl && ctrl->HasMouse();
}
void DisplayPopup::Set(Ctrl *_ctrl, const Rect& _item,
void DisplayPopup::PopUp::Set(Ctrl *_ctrl, const Rect& _item,
const Value& _value, const Display *_display,
Color _ink, Color _paper, dword _style, int _margin)
{
@ -212,4 +212,44 @@ void DisplayPopup::Set(Ctrl *_ctrl, const Rect& _item,
}
}
void DisplayPopup::Set(Ctrl *ctrl, const Rect& item, const Value& v, const Display *display, Color ink, Color paper, dword style, int margin)
{
if(!popup) {
popup.Create();
popup->usedisplaystdsize = usedisplaystdsize;
popup->WhenClose << [=] { PostCallback([=] { popup.Clear(); }); };
}
popup->Set(ctrl, item, v, display, ink, paper, style, margin);
}
void DisplayPopup::Cancel()
{
if(popup)
popup->Cancel();
}
bool DisplayPopup::IsOpen()
{
return popup && popup->IsOpen();
}
bool DisplayPopup::HasMouse()
{
return popup && popup->HasMouse();
}
void DisplayPopup::UseDisplayStdSize()
{
usedisplaystdsize = true;
if(popup)
popup->usedisplaystdsize = true;
}
DisplayPopup::~DisplayPopup()
{
if(popup)
popup->Close();
}
}

View file

@ -1,29 +1,52 @@
class DisplayPopup : public Ctrl, public Link<DisplayPopup> {
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword);
virtual void LeftDrag(Point p, dword);
virtual void LeftDouble(Point p, dword);
virtual void RightDown(Point p, dword);
virtual void LeftUp(Point p, dword);
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void MouseLeave();
virtual void MouseMove(Point p, dword);
class DisplayPopup {
private:
Ptr<Ctrl> ctrl;
Rect item;
Rect slim;
Value value;
Color paper, ink;
dword style;
const Display *display;
int margin;
struct PopUp : public Ctrl, public Link<DisplayPopup::PopUp> {
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword);
virtual void LeftDrag(Point p, dword);
virtual void LeftDouble(Point p, dword);
virtual void RightDown(Point p, dword);
virtual void LeftUp(Point p, dword);
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void MouseLeave();
virtual void MouseMove(Point p, dword);
Ptr<Ctrl> ctrl;
Rect item;
Rect slim;
Value value;
Color paper, ink;
dword style;
const Display *display;
int margin;
bool usedisplaystdsize = false;
Point Op(Point p);
void Sync();
static Vector<DisplayPopup::PopUp *>& all();
static bool StateHook(Ctrl *, int reason);
static bool MouseHook(Ctrl *, bool, int, Point, int, dword);
static void SyncAll();
typedef DisplayPopup::PopUp CLASSNAME;
Callback WhenClose;
void Set(Ctrl *ctrl, const Rect& item, const Value& v, const Display *display,
Color ink, Color paper, dword style, int margin = 0);
void Cancel();
bool IsOpen();
bool HasMouse();
PopUp();
~PopUp();
};
One<PopUp> popup;
bool usedisplaystdsize = false;
Point Op(Point p);
void Sync();
static Vector<DisplayPopup *>& all();
static bool StateHook(Ctrl *, int reason);
static bool MouseHook(Ctrl *, bool, int, Point, int, dword);
@ -37,8 +60,7 @@ public:
void Cancel();
bool IsOpen();
bool HasMouse();
void UseDisplayStdSize() { usedisplaystdsize = true; }
void UseDisplayStdSize();
DisplayPopup();
~DisplayPopup();
};

View file

@ -270,7 +270,7 @@ DropList::DropList()
dropfocus = false;
notnull = false;
alwaysdrop = false;
AddButton().Main().WhenPush = THISBACK(Drop);
SetupDropPush([=] { Drop(); });
NoInitFocus();
EnableDrop(false);
list.Normal();

View file

@ -164,6 +164,8 @@ protected:
virtual void PaintSpace(Draw& w);
virtual int GetSpaceLeft() const;
virtual int GetSpaceRight() const;
virtual void EditCapture();
virtual bool HasEditCapture();
public:
Event<Bar&> WhenBar;
@ -381,6 +383,7 @@ void WithSpin_Add(double& value, double inc, double min, bool roundfrommin) {
template <class DataType, class Base, class IncType = DataType>
class WithSpin : public Base, private VirtualButtons {
public:
virtual void CancelMode();
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual bool Key(dword key, int repcnt);
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags);
@ -388,6 +391,8 @@ public:
virtual int GetSpaceLeft() const;
virtual int GetSpaceRight() const;
virtual void PaintSpace(Draw& w);
virtual void EditCapture();
virtual bool HasEditCapture();
virtual int ButtonCount() const;
virtual Rect ButtonRect(int i) const;

View file

@ -119,6 +119,13 @@ void WithSpin<DataType, Base, IncType>::MouseWheel(Point, int zdelta, dword)
}
}
template <class DataType, class Base, class IncType>
void WithSpin<DataType, Base, IncType>::CancelMode()
{
Base::CancelMode();
ButtonsCancelMode();
}
template <class DataType, class Base, class IncType>
int WithSpin<DataType, Base, IncType>::GetSpaceLeft() const
{
@ -135,6 +142,18 @@ int WithSpin<DataType, Base, IncType>::GetSpaceRight() const
return min(Base::GetSize().cx / 2, style->width) - style->over;
}
template <class DataType, class Base, class IncType>
void WithSpin<DataType, Base, IncType>::EditCapture()
{
buttons_capture = false;
}
template <class DataType, class Base, class IncType>
bool WithSpin<DataType, Base, IncType>::HasEditCapture()
{
return Base::HasCapture() && !buttons_capture;
}
template <class DataType, class Base, class IncType>
void WithSpin<DataType, Base, IncType>::ButtonPush(int i)
{

View file

@ -197,6 +197,15 @@ int EditField::GetSpaceRight() const
return 0;
}
void EditField::EditCapture()
{
}
bool EditField::HasEditCapture()
{
return HasCapture();
}
int EditField::GetCursor(int posx)
{
posx -= GetSpaceLeft();
@ -506,6 +515,7 @@ void EditField::LeftDown(Point p, dword flags)
return;
}
SetCapture();
EditCapture();
Move(c, flags & K_SHIFT);
Finish();
}
@ -528,7 +538,7 @@ void EditField::LeftUp(Point p, dword flags)
{
int c = GetCursor(p.x + sc);
int l, h;
if(GetSelection(l, h) && c >= l && c < h && !HasCapture() && selclick)
if(GetSelection(l, h) && c >= l && c < h && !HasEditCapture() && selclick)
Move(c, false);
Finish();
selclick = false;
@ -550,7 +560,7 @@ void EditField::LeftTriple(Point p, dword keyflags)
void EditField::MouseMove(Point p, dword flags)
{
if(!HasCapture()) return;
if(!HasEditCapture()) return;
Move(GetCursor(p.x + sc), true);
Finish();
}
@ -761,7 +771,7 @@ void EditField::LeftDrag(Point p, dword flags)
int c = GetCursor(p.x + sc);
Size ssz = StdSampleSize();
int sell, selh;
if(!HasCapture() && GetSelection(sell, selh) && c >= sell && c <= selh) {
if(!HasEditCapture() && GetSelection(sell, selh) && c >= sell && c <= selh) {
WString sel = text.Mid(sell, selh - sell);
ImageDraw iw(ssz);
iw.DrawText(0, 0, sel);

View file

@ -47,9 +47,11 @@ MultiButton::SubButton::SubButton()
void MultiButton::SubButton::Refresh()
{
owner->Refresh();
if(owner->Frame() && owner->GetParent())
owner->GetParent()->RefreshLayout();
if(owner) {
owner->Refresh();
if(owner->Frame() && owner->GetParent())
owner->GetParent()->RefreshLayout();
}
}
MultiButton::SubButton& MultiButton::SubButton::SetImage(const Image& m)
@ -111,30 +113,89 @@ MultiButton::SubButton& MultiButton::SubButton::Show(bool b)
return *this;
}
void MultiButton::MultiButtons()
{
if(DropPush) {
SubButton& b = buttons.Add();
b.owner = this;
b.WhenPush = DropPush;
b.main = true;
DropPush.Clear();
}
}
MultiButton::SubButton& MultiButton::AddButton()
{
SubButton& b = button.Add();
MultiButtons();
SubButton& b = buttons.Add();
b.owner = this;
return b;
}
MultiButton::SubButton& MultiButton::InsertButton(int i)
{
SubButton& b = button.Insert(i);
MultiButtons();
SubButton& b = buttons.Insert(i);
b.owner = this;
return b;
}
void MultiButton::RemoveButton(int i)
{
button.Remove(i);
MultiButtons();
buttons.Remove(i);
}
void MultiButton::Reset()
{
MultiButtons();
buttons.Clear();
}
int MultiButton::GetButtonCount() const
{
if(DropPush)
return 1;
return buttons.GetCount();
}
MultiButton::SubButton& MultiButton::Button(int i) const
{
if(DropPush) {
static SubButton b;
b.main = true;
return b;
}
return const_cast<MultiButton *>(this)->buttons[i];
}
const MultiButton::SubButton& MultiButton::GetButton(int i) const
{
return Button(i);
}
MultiButton::SubButton& MultiButton::GetButton(int i)
{
MultiButtons();
return Button(i);
}
MultiButton::SubButton& MultiButton::MainButton()
{
for(int i = 0; i < GetButtonCount(); i++) {
SubButton& b = GetButton(i);
if(b.main)
return b;
}
NEVER();
return GetButton(0);
}
MultiButton::SubButton& MultiButton::SubButton::Main(bool b)
{
if(b)
for(int i = 0; i < owner->button.GetCount(); i++)
owner->button[i].main = false;
if(b && owner)
for(int i = 0; i < owner->GetButtonCount(); i++)
owner->GetButton(i).main = false;
main = b;
return *this;
}
@ -212,12 +273,12 @@ int MultiButton::FindButton(int px)
{
if(IsReadOnly())
return Null;
if(IsTrivial() && !Frame())
return button[0].enabled ? 0 : Null;
if(IsTrivial() && !Frame() && GetButtonCount())
return GetButton(0).enabled ? 0 : Null;
int border, lx, rx;
Metrics(border, lx, rx);
for(int i = 0; i < button.GetCount(); i++) {
SubButton& b = button[i];
for(int i = 0; i < GetButtonCount(); i++) {
SubButton& b = Button(i);
int x = 0, cx = 0;
if(GetPos(b, lx, rx, x, cx, px))
return b.enabled ? i : Null;
@ -225,8 +286,8 @@ int MultiButton::FindButton(int px)
if(WhenPush || WhenClick)
return MAIN;
if(display)
for(int i = 0; i < button.GetCount(); i++)
if(button[i].main)
for(int i = 0; i < GetButtonCount(); i++)
if(Button(i).main)
return i;
return Null;
}
@ -262,7 +323,7 @@ void MultiButton::GetPos(int ii, int& x, int& cx)
Metrics(border, lx, rx);
x = cx = 0;
for(int i = 0; i <= ii; i++) {
SubButton& b = button[i];
SubButton& b = Button(i);
GetPos(b, lx, rx, x, cx);
}
}
@ -273,8 +334,8 @@ void MultiButton::GetLR(int& lx, int& rx)
Metrics(border, lx, rx);
int x = 0;
int cx = 0;
for(int i = 0; i < button.GetCount(); i++) {
SubButton& b = button[i];
for(int i = 0; i < GetButtonCount(); i++) {
SubButton& b = Button(i);
GetPos(b, lx, rx, x, cx);
}
}
@ -286,13 +347,13 @@ int MultiButton::ChState(int i)
if(i == MAIN && frm && style->activeedge) {
int q = 0;
if(p)
q = !p->IsEnabled() || !IsEnabled() || p->IsReadOnly() || i >= 0 && !button[i].enabled ? CTRL_DISABLED
q = !p->IsEnabled() || !IsEnabled() || p->IsReadOnly() ? CTRL_DISABLED
: p->HasFocus() || push ? CTRL_PRESSED
: p->HasMouse() || hl >= 0 ? CTRL_HOT
: CTRL_NORMAL;
return q;
}
if(!IsShowEnabled() || IsReadOnly() || frm && p && p->IsReadOnly() || i >= 0 && !button[i].enabled)
if(!IsShowEnabled() || IsReadOnly() || frm && p && p->IsReadOnly() || i >= 0 && !Button(i).enabled)
return CTRL_DISABLED;
if(IsTrivial() && !frm)
i = 0;
@ -317,8 +378,8 @@ void MultiButton::Lay(Rect& r, bool minsize)
bool frm = Metrics(border, lx, rx);
bool left = false;
bool right = false;
for(int i = 0; i < button.GetCount(); i++) {
SubButton& b = button[i];
for(int i = 0; i < GetButtonCount(); i++) {
SubButton& b = Button(i);
int cx = 0; int x = 0;
GetPos(b, lx, rx, x, cx);
(b.left ? left : right) = true;
@ -404,8 +465,8 @@ Rect MultiButton::Paint0(Draw& w, bool getcr)
}
bool left = false;
bool right = false;
for(int i = 0; i < button.GetCount(); i++) {
SubButton& b = button[i];
for(int i = 0; i < GetButtonCount(); i++) {
SubButton& b = Button(i);
int st = ChState(i);
int x = 0, cx = 0;
GetPos(b, lx, rx, x, cx);
@ -562,7 +623,7 @@ void MultiButton::SyncInfo()
void MultiButton::MouseMove(Point p, dword flags)
{
int h = FindButton(p.x);
Ctrl::Tip(h >= 0 && h < button.GetCount() ? Nvl(button[h].tip, tip) : tip);
Ctrl::Tip(h >= 0 && h < GetButtonCount() ? Nvl(Button(h).tip, tip) : tip);
if(hl != h) {
hl = h;
Refresh();
@ -575,12 +636,20 @@ void MultiButton::MouseMove(Point p, dword flags)
SyncInfo();
}
void MultiButton::DoPush(int i)
{
if(i == 0 && DropPush)
DropPush();
else
Button(i).WhenPush();
}
void MultiButton::LeftDown(Point p, dword flags)
{
push = true;
Refresh();
if(IsNull(hl))
pushrect = Null;
if(hl == NONE)
pushrect.Clear();
else {
if(hl == MAIN)
pushrect = GetScreenRect();
@ -593,7 +662,7 @@ void MultiButton::LeftDown(Point p, dword flags)
}
Sync();
if(hl >= 0)
button[hl].WhenPush();
DoPush(hl);
else
WhenPush();
}
@ -605,9 +674,9 @@ void MultiButton::LeftUp(Point p, dword flags)
push = false;
Refresh();
Sync();
if(!IsNull(hl)) {
if(hl != NONE) {
if(hl >= 0)
button[hl].WhenClick();
Button(hl).WhenClick();
else
WhenClick();
}
@ -617,7 +686,7 @@ void MultiButton::LeftUp(Point p, dword flags)
void MultiButton::MouseLeave()
{
if(!info.IsOpen()) {
hl = Null;
hl = NONE;
Refresh();
SyncInfo();
}
@ -625,7 +694,7 @@ void MultiButton::MouseLeave()
void MultiButton::CancelMode()
{
hl = Null;
hl = NONE;
push = false;
Refresh();
info.Cancel();
@ -633,21 +702,7 @@ void MultiButton::CancelMode()
bool MultiButton::IsTrivial() const
{
return button.GetCount() == 1 && IsNull(button[0].img) && !WhenPush && !WhenClick;
}
MultiButton::SubButton& MultiButton::MainButton()
{
for(int i = 0; i < button.GetCount(); i++)
if(button[i].main)
return button[i];
NEVER();
return button[0];
}
void MultiButton::Reset()
{
button.Clear();
return GetButtonCount() == 1 && IsNull(Button(0).img) && !WhenPush && !WhenClick;
}
MultiButton& MultiButton::SetDisplay(const Display& d)
@ -718,11 +773,11 @@ void MultiButton::PseudoPush(int bi)
{
hl = bi;
push = true;
button[bi].WhenPush();
DoPush(bi);
Sync();
Sleep(50);
button[bi].WhenClick();
hl = Null;
Button(bi).WhenClick();
hl = NONE;
push = false;
Sync();
}
@ -734,7 +789,7 @@ void MultiButton::PseudoPush()
Sync();
Sleep(50);
WhenClick();
hl = Null;
hl = NONE;
push = false;
Sync();
}
@ -749,6 +804,7 @@ MultiButton::MultiButton()
push = false;
SetFrame(sNullFrame());
nobg = false;
hl = NONE;
}
void MultiButtonFrame::FrameAdd(Ctrl& parent)

View file

@ -49,8 +49,9 @@ public:
class SubButton {
friend class MultiButton;
String label;
String tip;
MultiButton *owner;
MultiButton *owner = nullptr;
Image img;
int cx;
bool main;
@ -59,8 +60,6 @@ public:
bool enabled;
bool visible;
String label;
void Refresh();
public:
@ -85,6 +84,7 @@ public:
private:
enum {
NONE = -2,
MAIN = -1,
LB_IMAGE = 5, // image <-> text space
LB_MARGIN = 10
@ -92,23 +92,25 @@ private:
virtual bool Frame();
const Display *display;
const Convert *convert;
DisplayPopup info;
Array<SubButton> buttons;
Event<> DropPush; // mode for droplist with single button
Value value;
Value error;
int valuecy;
bool push;
bool nobg;
String tip;
Rect pushrect;
Color paper = Null;
Array<SubButton> button;
int hl;
Rect16 pushrect;
const Display *display;
const Convert *convert;
const Style *style;
DisplayPopup info;
int valuecy;
Color paper = Null;
int16 hl;
bool push:1;
bool nobg:1;
int FindButton(int px);
void Margins(int& l, int& r);
@ -124,6 +126,9 @@ private:
bool Metrics(int& border, int& lx, int &rx);
void SyncInfo();
Rect Paint0(Draw& w, bool getcr);
void DoPush(int i);
void MultiButtons();
SubButton& Button(int i) const;
friend class SubButton;
friend class MultiButtonFrame;
@ -145,8 +150,9 @@ public:
SubButton& AddButton();
SubButton& InsertButton(int i);
void RemoveButton(int i);
int GetButtonCount() const { return button.GetCount(); }
SubButton& GetButton(int i) { return button[i]; }
int GetButtonCount() const;
const MultiButton::SubButton& GetButton(int i) const;
SubButton& GetButton(int i);
SubButton& MainButton();
Rect GetPushScreenRect() const { return pushrect; }
@ -168,6 +174,8 @@ public:
MultiButton& NoBackground(bool b = true);
MultiButton& SetStyle(const Style& s) { style = &s; Refresh(); return *this; }
void SetupDropPush(Event<> push) { DropPush = push; }
MultiButton();
};

View file

@ -423,14 +423,15 @@ struct VirtualButtons {
virtual void ButtonRepeat(int i);
virtual void ButtonAction(int i);
int16 pushi = -1;
int16 mi = -1;
int8 pushi = -1;
int8 mi = -1;
bool buttons_capture = false;
int FindButton(Point p) const;
void EndPush(Ctrl *ctrl);
bool ButtonsCancelMode(Ctrl *ctrl);
void ButtonsCancelMode();
bool ButtonsMouseEvent(Ctrl *ctrl, int event, Point p);
void PaintButtons(Draw& w, Ctrl *ctrl);

View file

@ -214,7 +214,7 @@ void ScrollBar::Paint(Draw& w)
Size sz = style->through ? GetSize() : Slider(cc).GetSize();
light = GetMousePart();
int p = push;
if(!HasCapture())
if(!HasCapture() || buttons_capture)
p = -1;
const Value *hl[] = { style->hlower, style->hupper, style->hthumb };
const Value *vl[] = { style->vupper, style->vlower, style->vthumb };
@ -229,7 +229,7 @@ void ScrollBar::Paint(Draw& w)
pr = style->through ? GetSize() : Slider();
}
if(i != 2 || thumbsize >= style->thumbmin)
ChPaint(w, pr, l[i][p == i ? CTRL_PRESSED : light == i ? CTRL_HOT : CTRL_NORMAL]);
ChPaint(w, pr, l[i][p == i ? CTRL_PRESSED : light == i && !buttons_capture ? CTRL_HOT : CTRL_NORMAL]);
if(i != 2)
w.End();
}
@ -325,6 +325,7 @@ void ScrollBar::LeftDown(Point p, dword) {
NextPage();
}
SetCapture();
buttons_capture = false;
Refresh();
WhenLeftClick();
}
@ -371,6 +372,7 @@ void ScrollBar::MouseWheel(Point p, int zdelta, dword keyflags)
void ScrollBar::CancelMode() {
push = light = -1;
ButtonsCancelMode();
}
bool ScrollBar::Set(int apagepos) {

View file

@ -23,6 +23,8 @@ int VirtualButtons::FindButton(Point p) const
int VirtualButtons::ButtonVisualState(Ctrl *ctrl, int i)
{
if(ctrl->HasCapture() && !buttons_capture)
return CTRL_NORMAL;
if(ButtonEnabled(i)) {
if(i == pushi)
return CTRL_PRESSED;
@ -55,8 +57,17 @@ void VirtualButtons::RefreshButton(Ctrl *ctrl, int i)
ctrl->Refresh(ButtonRect(i));
}
void VirtualButtons::ButtonsCancelMode()
{
pushi = -1;
mi = -1;
buttons_capture = false;
}
bool VirtualButtons::ButtonsMouseEvent(Ctrl *ctrl, int event, Point p)
{
if(ctrl->HasCapture() && !buttons_capture)
return false;
int i = event == Ctrl::MOUSELEAVE ? -1 : FindButton(p);
if(i != mi) {
RefreshButton(ctrl, mi);
@ -70,6 +81,7 @@ bool VirtualButtons::ButtonsMouseEvent(Ctrl *ctrl, int event, Point p)
if(pushi >= 0) {
ButtonPush(i);
ctrl->SetCapture();
buttons_capture = true;
}
else
EndPush(ctrl);
@ -90,6 +102,7 @@ bool VirtualButtons::ButtonsMouseEvent(Ctrl *ctrl, int event, Point p)
if(ii >= 0) {
EndPush(ctrl);
ReleaseCapture();
buttons_capture = false;
ButtonAction(ii);
}
break;