mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
746 lines
18 KiB
C++
746 lines
18 KiB
C++
#include "CtrlLib.h"
|
|
|
|
namespace Upp {
|
|
|
|
#define LLOG(x) // LOG(x)
|
|
|
|
void BarPane::LeftDown(Point pt, dword keyflags)
|
|
{
|
|
WhenLeftClick();
|
|
}
|
|
|
|
void BarPane::PaintBar(Draw& w, const SeparatorCtrl::Style& ss, const Value& pane,
|
|
const Value& iconbar, int iconsz)
|
|
{
|
|
Size sz = GetSize();
|
|
Rect r = sz;
|
|
for(int i = 0; i < breakpos.GetCount(); i++)
|
|
if(horz) {
|
|
int y = breakpos[i];
|
|
Rect rr = r;
|
|
rr.bottom = y;
|
|
ChPaint(w, rr, pane);
|
|
if(!IsNull(ss.l1))
|
|
ChPaint(w, 0, y++, sz.cx, 1, ss.l1);
|
|
if(!IsNull(ss.l2))
|
|
ChPaint(w, 0, y++, sz.cx, 1, ss.l2);
|
|
r.top = y;
|
|
}
|
|
else {
|
|
int x = breakpos[i];
|
|
Rect rr = r;
|
|
rr.right = x;
|
|
if(!IsNull(iconbar)) {
|
|
Rect r2 = rr;
|
|
r2.right = r2.left + iconsz;
|
|
ChPaint(w, r2, iconbar);
|
|
rr.left = r2.right;
|
|
}
|
|
ChPaint(w, rr, pane);
|
|
if(!IsNull(ss.l1))
|
|
ChPaint(w, x++, 0, 1, sz.cy, ss.l1);
|
|
if(!IsNull(ss.l2))
|
|
ChPaint(w, x++, 0, 1, sz.cy, ss.l2);
|
|
r.left = x;
|
|
}
|
|
if(!horz && !IsNull(iconbar)) {
|
|
Rect r2 = r;
|
|
r2.right = r2.left + iconsz;
|
|
ChPaint(w, r2, iconbar);
|
|
r.left = r2.right;
|
|
}
|
|
ChPaint(w, r, pane);
|
|
}
|
|
|
|
Size BarPane::LayOut(bool horz, int maxsize, bool repos)
|
|
{
|
|
auto HoVe = [&](Size& sz)->int& { return horz ? sz.cx : sz.cy; };
|
|
auto VeHo = [&](Size& sz)->int& { return horz ? sz.cy : sz.cx; };
|
|
maxsize -= 2 * (horz ? hmargin : vmargin);
|
|
if(repos) {
|
|
this->horz = horz;
|
|
breakpos.Clear();
|
|
}
|
|
int bmargin = horz ? vmargin : hmargin;
|
|
Size asz(0, 0);
|
|
VeHo(asz) = bmargin;
|
|
auto q = item.begin();
|
|
while(q != item.end()) {
|
|
Size psz(0, 0);
|
|
auto f = q;
|
|
while(q != item.end()) {
|
|
if(q->ctrl == NULL && IsNull(q->gapsize)) {
|
|
q++;
|
|
break;
|
|
}
|
|
int gapsize = q->gapsize;
|
|
if(gapsize == INT_MAX && q->ctrl == NULL) {
|
|
if(maxsize == INT_MAX) {
|
|
q++;
|
|
break;
|
|
}
|
|
int rsz = 0;
|
|
auto w = q + 1;
|
|
while(w < item.end()) {
|
|
if(!w->ctrl) break;
|
|
Size sz = w->ctrl->GetMinSize();
|
|
// if(HoVe(psz) + gapsize + HoVe(sz) > maxsize) break;
|
|
rsz += HoVe(sz);
|
|
w++;
|
|
}
|
|
if(rsz > maxsize)
|
|
gapsize = 0;
|
|
else {
|
|
gapsize = maxsize - rsz - HoVe(psz);
|
|
if(gapsize < 0)
|
|
gapsize = maxsize - rsz;
|
|
}
|
|
}
|
|
Size sz = q->ctrl ? q->ctrl->GetMinSize()
|
|
: Size(horz ? gapsize : 0, horz ? 0 : gapsize);
|
|
if(HoVe(sz) == INT_MAX)
|
|
HoVe(sz) = maxsize - HoVe(psz);
|
|
if(HoVe(psz) + HoVe(sz) > maxsize && HoVe(psz)) {
|
|
while(q < item.end() && q->ctrl == NULL && !IsNull(q->gapsize) && q->gapsize != INT_MAX)
|
|
q++;
|
|
break;
|
|
}
|
|
VeHo(psz) = max(VeHo(psz), VeHo(sz));
|
|
if(q->ctrl) {
|
|
if(horz)
|
|
q->ctrl->LeftPos(min(psz.cx + hmargin, 32000), sz.cx);
|
|
else
|
|
q->ctrl->TopPos(min(psz.cy + vmargin, 32000), sz.cy);
|
|
}
|
|
HoVe(psz) += HoVe(sz);
|
|
q++;
|
|
}
|
|
int& bp = VeHo(asz);
|
|
if(bp > bmargin) {
|
|
if(repos)
|
|
breakpos.Add(bp + bmargin);
|
|
bp += 2 + 2 * bmargin;
|
|
}
|
|
if(repos)
|
|
while(f != q) {
|
|
if(f->ctrl) {
|
|
int bpm = min(bp, 32000);
|
|
if(horz)
|
|
f->ctrl->TopPos(bpm, psz.cy);
|
|
else
|
|
f->ctrl->LeftPos(bpm, psz.cx);
|
|
}
|
|
f++;
|
|
}
|
|
bp += VeHo(psz);
|
|
HoVe(asz) = max(HoVe(asz), HoVe(psz));
|
|
}
|
|
VeHo(asz) += bmargin;
|
|
HoVe(asz) += horz ? 2 * hmargin : 2 * vmargin;
|
|
LLOG("Repos " << Name() << " " << asz);
|
|
return asz;
|
|
}
|
|
|
|
|
|
Size BarPane::Repos(bool horz, int maxsize)
|
|
{
|
|
return LayOut(horz, maxsize, true);
|
|
}
|
|
|
|
Size BarPane::GetPaneSize(bool _horz, int maxsize) const
|
|
{
|
|
return const_cast<BarPane *>(this)->LayOut(horz, maxsize, false);
|
|
}
|
|
|
|
void BarPane::IClear()
|
|
{
|
|
breakpos.Clear();
|
|
item.Clear();
|
|
}
|
|
|
|
void BarPane::Clear()
|
|
{
|
|
while(GetFirstChild())
|
|
RemoveChild(GetFirstChild());
|
|
IClear();
|
|
}
|
|
|
|
void BarPane::Add(Ctrl *ctrl, int gapsize)
|
|
{
|
|
Item& m = item.Add();
|
|
m.ctrl = ctrl;
|
|
m.gapsize = gapsize;
|
|
if(ctrl)
|
|
AddChild(ctrl);
|
|
}
|
|
|
|
void BarPane::MouseMove(Point p, dword)
|
|
{
|
|
Ctrl *q = Ctrl::GetVisibleChild(this, p, false);
|
|
if(q != phelpctrl) {
|
|
phelpctrl = q;
|
|
BarCtrl::SendHelpLine(q);
|
|
}
|
|
}
|
|
|
|
BarPane::BarPane()
|
|
{
|
|
NoWantFocus();
|
|
phelpctrl = NULL;
|
|
hmargin = vmargin = 0;
|
|
menu = false;
|
|
}
|
|
|
|
BarPane::~BarPane() {}
|
|
|
|
Bar::Item::Item() {}
|
|
Bar::Item::~Item() {}
|
|
|
|
Bar::Item& Bar::Item::Text(const char *text) { return *this; }
|
|
Bar::Item& Bar::Item::Key(dword key) { return *this; }
|
|
Bar::Item& Bar::Item::Repeat(bool b) { return *this; }
|
|
Bar::Item& Bar::Item::Image(const UPP::Image& img) { return *this; }
|
|
Bar::Item& Bar::Item::Bold(bool bold) { return *this; }
|
|
Bar::Item& Bar::Item::Enable(bool _enable) { return *this; }
|
|
Bar::Item& Bar::Item::Tip(const char *tip) { return *this; }
|
|
Bar::Item& Bar::Item::Help(const char *help) { return *this; }
|
|
Bar::Item& Bar::Item::Topic(const char *topic) { return *this; }
|
|
Bar::Item& Bar::Item::Description(const char *desc) { return *this; }
|
|
Bar::Item& Bar::Item::Check(bool check) { return *this; }
|
|
Bar::Item& Bar::Item::Radio(bool check) { return *this; }
|
|
void Bar::Item::FinalSync() {}
|
|
|
|
Bar::Item& Bar::Item::Label(const char *text)
|
|
{
|
|
ToolButton *b = dynamic_cast<ToolButton *>(this);
|
|
if(b) b->Label(text, ToolButton::BOTTOMLABEL);
|
|
return *this;
|
|
}
|
|
|
|
Bar::Item& Bar::Item::RightLabel(const char *text)
|
|
{
|
|
ToolButton *b = dynamic_cast<ToolButton *>(this);
|
|
if(b) b->Label(text, ToolButton::RIGHTLABEL);
|
|
return *this;
|
|
}
|
|
|
|
Bar::Item& Bar::Item::Key(KeyInfo& (*key)()) {
|
|
KeyInfo& k = (*key)();
|
|
return Key(k.key[0]).Key(k.key[1]).Key(k.key[2]).Key(k.key[3]);
|
|
}
|
|
|
|
Bar::Bar() {}
|
|
Bar::~Bar() {}
|
|
|
|
Bar::Item& Bar::NilItem()
|
|
{
|
|
static Item m;
|
|
return m;
|
|
}
|
|
|
|
void Bar::AddNC(Ctrl& ctrl)
|
|
{
|
|
AddCtrl(&ctrl, (int)Null);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const UPP::Image& image, const Callback& callback)
|
|
{
|
|
return AddItem(callback).Text(text).Image(image).Enable(enable);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, KeyInfo& (*key)(), const UPP::Image& image, const Callback& callback)
|
|
{
|
|
const char *text = (*key)().name;
|
|
if(*text == '\3')
|
|
text = t_GetLngString(text + 1);
|
|
return Add(enable, text, image, callback).Key(key);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(const char *text, const UPP::Image& image, const Callback& callback)
|
|
{
|
|
return AddItem(callback).Text(text).Image(image);
|
|
}
|
|
/*
|
|
Bar::Item& Bar::Add(const String& text, const UPP::Image& image, const Event<> & callback)
|
|
{
|
|
return Add(~text, image, callback);
|
|
}
|
|
*/
|
|
Bar::Item& Bar::Add(KeyInfo& (*key)(), const UPP::Image& image, const Callback& callback)
|
|
{
|
|
const char *text = (*key)().name;
|
|
if(*text == '\3')
|
|
text = t_GetLngString(text + 1);
|
|
return Add(text, image, callback).Key(key);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(enable, text, Image(), callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::Add(const char *text, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(true, text, Image(), callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::Add(bool enable, KeyInfo& (*key)(), const Callback & callback)
|
|
{ return IsMenuBar() ? Add(enable, key, Image(), callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::Add(KeyInfo& (*key)(), const Callback & callback)
|
|
{ return IsMenuBar() ? Add(true, key, Image(), callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const UPP::Image& image, const UPP::Function<void ()>& fn)
|
|
{
|
|
return Add(enable, text, image, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, KeyInfo& (*key)(), const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return Add(enable, key, image, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(const char *text, const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return Add(text, image, Callback() << fn);
|
|
}
|
|
|
|
/*
|
|
Bar::Item& Bar::Add(const String& text, const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return Add(text, image, Event<> () << fn);
|
|
}
|
|
*/
|
|
|
|
Bar::Item& Bar::Add(KeyInfo& (*key)(), const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return Add(key, image, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const Function<void ()>& fn)
|
|
{
|
|
return Add(enable, text, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, KeyInfo& (*key)(), const Function<void ()>& fn)
|
|
{
|
|
return Add(enable, key, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(const char *text, const Function<void ()>& fn)
|
|
{
|
|
return Add(text, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(KeyInfo& (*key)(), const Function<void ()>& fn)
|
|
{
|
|
return Add(key, Callback() << fn);
|
|
}
|
|
|
|
void Bar::Break()
|
|
{
|
|
AddCtrl(NULL, (int)Null);
|
|
}
|
|
|
|
void Bar::Gap(int size)
|
|
{
|
|
AddCtrl(NULL, size);
|
|
}
|
|
|
|
void Bar::MenuSeparator() { if(IsMenuBar()) Separator(); }
|
|
void Bar::MenuBreak() { if(IsMenuBar()) Break(); }
|
|
void Bar::MenuGap(int size) { if(IsMenuBar()) Gap(size); }
|
|
void Bar::AddMenu(Ctrl& ctrl) { if(IsMenuBar()) Add(ctrl); }
|
|
void Bar::AddMenu(Ctrl& ctrl, Size sz) { if(IsMenuBar()) Add(ctrl, sz); }
|
|
|
|
Bar::Item& Bar::AddMenu(bool enable, KeyInfo& (*key)(), const UPP::Image& image, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(enable, key, image, callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::AddMenu(KeyInfo& (*key)(), const UPP::Image& image, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(key, image, callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::AddMenu(bool enable, const char *text, const UPP::Image& image, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(enable, text, image, callback) : NilItem(); }
|
|
|
|
Bar::Item& Bar::AddMenu(const char *text, const UPP::Image& image, const Callback & callback)
|
|
{ return IsMenuBar() ? Add(text, image, callback) : NilItem(); }
|
|
|
|
|
|
Bar::Item& Bar::AddMenu(bool enable, const char *text, const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return AddMenu(enable, text, image, Callback() << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::AddMenu(bool enable, KeyInfo& (*key)(), const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return AddMenu(enable, key, image, Callback () << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::AddMenu(const char *text, const UPP::Image& image, const Function<void ()>& fn)
|
|
{
|
|
return AddMenu(text, image, Callback () << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::AddMenu(KeyInfo& (*key)(), const UPP::Image& m, const Function<void ()>& fn)
|
|
{
|
|
return AddMenu(key, m, Callback () << fn);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const Callback1<Bar&>& proc)
|
|
{ return AddSubMenu(proc).Text(text).Enable(enable); }
|
|
|
|
Bar::Item& Bar::Add(const char *text, const Callback1<Bar&>& proc)
|
|
{ return Add(true, text, proc); }
|
|
|
|
Bar::Item& Bar::Add(bool enable, const char *text, const UPP::Image& image, const Callback1<Bar&>& proc)
|
|
{ return Add(enable, text, proc).Image(image); }
|
|
|
|
Bar::Item& Bar::Add(const char *text, const UPP::Image& image, const Callback1<Bar&>& proc)
|
|
{ return Add(text, proc).Image(image); }
|
|
|
|
Bar::Item& Bar::Sub(bool enable, const char *text, const Function<void (Bar&)>& submenu)
|
|
{
|
|
return Add(enable, text, Callback1<Bar&>() << submenu);
|
|
}
|
|
|
|
Bar::Item& Bar::Sub(const char *text, const Function<void (Bar&)>& submenu)
|
|
{
|
|
return Add(text, Callback1<Bar&>() << submenu);
|
|
}
|
|
|
|
Bar::Item& Bar::Sub(bool enable, const char *text, const UPP::Image& image, const Function<void (Bar&)>& submenu)
|
|
{
|
|
return Add(enable, text, image, Callback1<Bar&>() << submenu);
|
|
}
|
|
|
|
Bar::Item& Bar::Sub(const char *text, const UPP::Image& image, const Function<void (Bar&)>& submenu)
|
|
{
|
|
return Add(text, image, Callback1<Bar&>() << submenu);
|
|
}
|
|
|
|
void Bar::ToolSeparator() { if(IsToolBar()) Separator(); }
|
|
void Bar::ToolBreak() { if(IsToolBar()) Break(); }
|
|
void Bar::ToolGap(int size) { if(IsToolBar()) Gap(size); }
|
|
|
|
void Bar::AddTool(Ctrl& ctrl) { if(IsToolBar()) Add(ctrl); }
|
|
void Bar::AddTool(Ctrl& ctrl, Size sz) { if(IsToolBar()) Add(ctrl, sz); }
|
|
|
|
void Bar::AddKey(dword key, Event<> cb) {}
|
|
|
|
void Bar::AddKey(KeyInfo& (*key)(), Event<> cb)
|
|
{
|
|
KeyInfo& k = (*key)();
|
|
AddKey(k.key[0], cb);
|
|
AddKey(k.key[1], cb);
|
|
AddKey(k.key[2], cb);
|
|
AddKey(k.key[3], cb);
|
|
}
|
|
|
|
Bar::Item& Bar::Add(bool enable, const UPP::Image& image, Event<> cb)
|
|
{ return IsToolBar() ? AddItem(cb).Image(image).Enable(enable) : NilItem(); }
|
|
|
|
Bar::Item& Bar::Add(const UPP::Image& image, Event<> cb)
|
|
{ return IsToolBar() ? Add(true, image, cb) : NilItem(); }
|
|
|
|
class Bar::ScanKeys : public Bar {
|
|
struct KeyItem : public Bar::Item {
|
|
bool enabled;
|
|
Vector<dword> key;
|
|
Event<> action;
|
|
|
|
virtual Item& Text(const char *) { return *this; }
|
|
virtual Item& Check(bool check) { return *this; }
|
|
virtual Item& Radio(bool check) { return *this; }
|
|
virtual Item& Key(dword _key) { if(_key) key.Add(_key); return *this; }
|
|
virtual Item& Image(const UPP::Image& img) { return *this; }
|
|
virtual Item& Enable(bool _enable = true) { enabled = _enable; return *this; }
|
|
virtual Item& Tip(const char *tip) { return *this; }
|
|
virtual Item& Help(const char *help) { return *this; }
|
|
virtual Item& Topic(const char *help) { return *this; }
|
|
virtual Item& Description(const char *help) { return *this; }
|
|
};
|
|
|
|
Array<KeyItem> key;
|
|
KeyItem nilitem;
|
|
int level;
|
|
|
|
protected:
|
|
virtual Item& AddItem(Event<> cb);
|
|
virtual Item& AddSubMenu(Event<Bar&> proc);
|
|
virtual void AddCtrl(Ctrl *ctrl, int gapsize) {};
|
|
virtual void AddCtrl(Ctrl *ctrl, Size sz) {};
|
|
|
|
public:
|
|
virtual bool IsMenuBar() const { return true; }
|
|
virtual bool IsToolBar() const { return true; }
|
|
virtual bool IsScanKeys() const { return true; }
|
|
|
|
virtual bool IsEmpty() const { return key.IsEmpty(); }
|
|
virtual void Separator() {}
|
|
virtual void AddKey(dword key, Event<> cb);
|
|
|
|
bool Do(dword key);
|
|
|
|
ScanKeys() { level = 0; }
|
|
};
|
|
|
|
Bar::Item& Bar::ScanKeys::AddItem(Event<> cb)
|
|
{
|
|
KeyItem& m = key.Add();
|
|
m.action = cb;
|
|
m.enabled = true;
|
|
return m;
|
|
}
|
|
|
|
Bar::Item& Bar::ScanKeys::AddSubMenu(Event<Bar&> proc)
|
|
{
|
|
level++;
|
|
if(level > 5)
|
|
return NilItem();;
|
|
proc(*this);
|
|
level--;
|
|
return key.GetCount() ? key.Top() : nilitem;
|
|
}
|
|
|
|
void Bar::ScanKeys::AddKey(dword _key, Event<> cb)
|
|
{
|
|
if(_key) {
|
|
KeyItem& m = key.Add();
|
|
m.action = cb;
|
|
m.enabled = true;
|
|
m.key.Add(_key);
|
|
}
|
|
}
|
|
|
|
bool Bar::ScanKeys::Do(dword k)
|
|
{
|
|
for(int i = 0; i < key.GetCount(); i++) {
|
|
KeyItem& m = key[i];
|
|
if(m.enabled && FindIndex(m.key, k) >= 0) {
|
|
m.action();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Bar::Scan(Event<Bar&> proc, dword key)
|
|
{
|
|
ScanKeys keys;
|
|
proc(keys);
|
|
return keys.Do(key);
|
|
}
|
|
|
|
bool BarCtrl::IsEmpty() const
|
|
{
|
|
return pane.IsEmpty();
|
|
}
|
|
|
|
void BarCtrl::Separator()
|
|
{
|
|
AddNC(separator.At(sii++).Margin(lsepm, rsepm).SetStyle(*sepstyle).SetSize(ssize));
|
|
}
|
|
|
|
void BarCtrl::AddCtrl(Ctrl *ctrl, Size sz)
|
|
{
|
|
SizeCtrl& m = sizer.DoIndex(zii++);
|
|
while(m.GetFirstChild())
|
|
m.RemoveChild(m.GetFirstChild());
|
|
LogPos p = ctrl->GetPos();
|
|
if(p.x.IsEmpty()) {
|
|
if(sz.cx == INT_MAX)
|
|
ctrl->HSizePos();
|
|
else
|
|
ctrl->HCenterPos(sz.cx ? sz.cx : MINSIZE);
|
|
}
|
|
if(p.y.IsEmpty()) {
|
|
if(sz.cy == INT_MAX)
|
|
ctrl->VSizePos();
|
|
else
|
|
ctrl->VCenterPos(sz.cy ? sz.cy : MINSIZE);
|
|
}
|
|
LLOG("AddCtrl Ctrl::GetSize: " << ctrl->GetSize());
|
|
m.SetSize(sz);
|
|
m.AddChild(ctrl);
|
|
AddNC(m);
|
|
LLOG("AddCtrl2 Ctrl::GetSize: " << ctrl->GetSize());
|
|
}
|
|
|
|
Size BarCtrl::SizeCtrl::GetMinSize() const
|
|
{
|
|
Size sz = size;
|
|
Size chsz = Size(8, 8);
|
|
if(GetFirstChild())
|
|
chsz = GetFirstChild()->GetStdSize();
|
|
sz.cx = sz.cx <= 0 ? chsz.cx : sz.cx;
|
|
sz.cy = sz.cy <= 0 ? chsz.cy : sz.cy;
|
|
return sz;
|
|
}
|
|
|
|
Value BarCtrl::GetBackground() const
|
|
{
|
|
return Null;
|
|
}
|
|
|
|
void BarCtrl::Clear()
|
|
{
|
|
separator.Clear();
|
|
sizer.Clear();
|
|
pane.Clear();
|
|
}
|
|
|
|
void BarCtrl::IClear()
|
|
{
|
|
sii = zii = 0;
|
|
pane.IClear();
|
|
}
|
|
|
|
void BarCtrl::IFinish()
|
|
{
|
|
separator.SetCount(sii);
|
|
sizer.SetCount(zii);
|
|
}
|
|
|
|
BarCtrl *BarCtrl::GetBarCtrlParent(Ctrl *q)
|
|
{
|
|
while(q) {
|
|
BarCtrl *w = dynamic_cast<BarCtrl *>(q);
|
|
if(w) return w;
|
|
q = q->GetParent();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void BarCtrl::SendHelpLine(Ctrl *q)
|
|
{
|
|
String s = q->GetHelpLine();
|
|
if(!UPP::IsEmpty(s)) {
|
|
BarCtrl *b = GetBarCtrlParent(q);
|
|
if(b) b->WhenHelp(s);
|
|
}
|
|
}
|
|
|
|
void BarCtrl::ClearHelpLine(Ctrl *q)
|
|
{
|
|
BarCtrl *b = GetBarCtrlParent(q);
|
|
if(b) b->WhenHelp(Null);
|
|
}
|
|
|
|
void BarCtrl::FrameLayout(Rect& r)
|
|
{
|
|
switch(align) {
|
|
case BAR_LEFT:
|
|
LayoutFrameLeft(r, this, pane.Repos(false, r.Height()).cx);
|
|
break;
|
|
case BAR_RIGHT:
|
|
LayoutFrameRight(r, this, pane.Repos(false, r.Height()).cx);
|
|
break;
|
|
case BAR_BOTTOM:
|
|
LayoutFrameBottom(r, this, pane.Repos(true, r.Width()).cy);
|
|
break;
|
|
default:
|
|
LayoutFrameTop(r, this, pane.Repos(true, r.Width()).cy);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BarCtrl::FrameAddSize(Size& sz)
|
|
{
|
|
if(align == BAR_LEFT || align == BAR_RIGHT)
|
|
sz.cx += pane.GetPaneSize(true, sz.cy).cx;
|
|
else
|
|
sz.cy += pane.GetPaneSize(true, sz.cx).cy;
|
|
}
|
|
|
|
void BarCtrl::FrameAdd(Ctrl& parent)
|
|
{
|
|
parent.Add(*this);
|
|
}
|
|
|
|
void BarCtrl::FrameRemove()
|
|
{
|
|
Remove();
|
|
}
|
|
|
|
void BarCtrl::AddCtrl(Ctrl *ctrl, int gapsize)
|
|
{
|
|
pane.Add(ctrl, gapsize);
|
|
}
|
|
|
|
BarCtrl& BarCtrl::Align(int al) {
|
|
align = al;
|
|
SyncBar();
|
|
return *this;
|
|
}
|
|
|
|
void BarCtrl::SyncBar()
|
|
{
|
|
if(IsChild() && InFrame())
|
|
UpdateParentLayout();
|
|
else
|
|
Layout();
|
|
}
|
|
|
|
void BarCtrl::Layout()
|
|
{
|
|
LLOG("BarCtrl::Layout");
|
|
if(IsChild()) {
|
|
bool dowrap = InFrame() && wrap >= 0 || wrap > 0;
|
|
if(GetAlign() == BAR_LEFT || GetAlign() == BAR_RIGHT)
|
|
pane.Repos(false, dowrap ? GetSize().cy : INT_MAX);
|
|
else
|
|
pane.Repos(true, dowrap ? GetSize().cx : INT_MAX);
|
|
}
|
|
}
|
|
|
|
void BarCtrl::PaintBar(Draw& w, const SeparatorCtrl::Style& ss, const Value& p, const Value& iconbar, int iconsz)
|
|
{
|
|
pane.PaintBar(w, ss, p, iconbar, iconsz);
|
|
}
|
|
|
|
BarCtrl::BarCtrl() {
|
|
align = BAR_TOP;
|
|
Ctrl::Add(pane.SizePos());
|
|
lsepm = rsepm = 2;
|
|
ssize = 8;
|
|
sii = zii = 0;
|
|
NoWantFocus();
|
|
pane.WhenLeftClick = Proxy(WhenLeftClick);
|
|
wrap = 0;
|
|
sepstyle = &SeparatorCtrl::StyleDefault();
|
|
}
|
|
|
|
BarCtrl::~BarCtrl() {}
|
|
|
|
void LRUList::Serialize(Stream& stream)
|
|
{
|
|
StreamContainer(stream, lru);
|
|
}
|
|
|
|
void LRUList::Select(String f, Event<const String&> WhenSelect)
|
|
{
|
|
WhenSelect(f);
|
|
}
|
|
|
|
void LRUList::operator()(Bar& bar, Event<const String&> WhenSelect, int count, int from)
|
|
{
|
|
if(bar.IsMenuBar() && !lru.IsEmpty()) {
|
|
bar.Separator();
|
|
char n = '1';
|
|
for(int i = from; i < min(from + count, lru.GetCount()); i++) {
|
|
bar.Add(String("&") + n + ' ' + GetFileName(lru[i]),
|
|
THISBACK2(Select, lru[i], WhenSelect));
|
|
n = n == '9' ? 'A' : n + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LRUList::NewEntry(const String& path)
|
|
{
|
|
LruAdd(lru, path, limit);
|
|
}
|
|
|
|
void LRUList::RemoveEntry(const String& path)
|
|
{
|
|
int q = FindIndex(lru, path);
|
|
if(q >= 0)
|
|
lru.Remove(q);
|
|
}
|
|
|
|
}
|