mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
VirtualButtons improvements
This commit is contained in:
parent
5a711f77ae
commit
67f810e0f5
12 changed files with 307 additions and 127 deletions
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ DropList::DropList()
|
|||
dropfocus = false;
|
||||
notnull = false;
|
||||
alwaysdrop = false;
|
||||
AddButton().Main().WhenPush = THISBACK(Drop);
|
||||
SetupDropPush([=] { Drop(); });
|
||||
NoInitFocus();
|
||||
EnableDrop(false);
|
||||
list.Normal();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue