ultimatepp/uppsrc/TCtrlLib/util.h
cxl 8ebdcbb0d5 uppsrc: NAMESPACE_UPP / END_UPP_NAMESPACE removed
git-svn-id: svn://ultimatepp.org/upp/trunk@10186 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2016-08-26 17:15:30 +00:00

556 lines
18 KiB
C++

namespace Upp {
#define ASSERT_INDEX(arrayctrl, index) ASSERT(arrayctrl.GetIndexCount() == index)
#define TOOL(x) \
void COMBINE(Tool, x)(Bar& bar); \
void COMBINE(On, x)(); \
static void COMBINE(Help, x)();
#define TOOL_LOCAL(x) \
void COMBINE(Tool, x)(Bar& bar, bool local); \
void COMBINE(On, x)(); \
static void COMBINE(Help, x)();
class Pump
{
public:
struct Item
{
virtual ~Item() {}
virtual void Run(bool write) = 0;
};
Pump() {}
void Run(bool write) { for(int i = 0; i < items.GetCount(); i++) items[i].Run(write); }
void Read() { Run(false); }
void Write() { Run(true); }
bool IsEmpty() const { return items.IsEmpty(); }
Pump& Add(Item *item) { items.Add(item); return *this; }
Pump& operator << (One<Item> item) { Add(-item); return *this; }
Pump& operator << (Item *item) { Add(item); return *this; }
void operator << (bool write) { Run(write); }
void Clear() { items.Clear(); }
public:
Array<Item> items;
};
inline Pump WithPump() { return Pump(); }
template <class A, class B>
struct PumpItemSet : public Pump::Item
{
PumpItemSet(A& a, B& b) : a(a), b(b) {}
virtual void Run(bool write) { if(write) a = b; else b = a; }
A& a; B& b;
};
template <class A, class B>
inline One<Pump::Item> PumpSet(A& a, B& b) { return new PumpItemSet<A, B>(a, b); }
template <class A, class B>
struct PumpItemData : public Pump::Item
{
PumpItemData(A& a, B& b) : a(a), b(b) {}
virtual void Run(bool write) { if(write) a = ~b; else b <<= a; }
A& a; B& b;
};
template <class A, class B>
inline One<Pump::Item> PumpData(A& a, B& b) { return new PumpItemData<A, B>(a, b); }
template <class B>
struct PumpItemDataRef : public Pump::Item
{
PumpItemDataRef(Ref ref, B& b) : ref(ref), b(b) {}
virtual void Run(bool write) { if(write) ref.SetValue(~b); else b <<= Value(ref); }
Ref ref; B& b;
};
template <class B>
inline One<Pump::Item> PumpDataRef(Ref ref, B& b) { return new PumpItemDataRef<B>(ref, b); }
template <class A, class B>
struct PumpItemEnumData : public Pump::Item
{
PumpItemEnumData(A& a, B& b) : a(a), b(b) {}
virtual void Run(bool write) { if(write) a = A(int(~b)); else b <<= (int)a; }
A& a; B& b;
};
template <class A, class B>
inline One<Pump::Item> PumpEnumData(A& a, B& b) { return new PumpItemEnumData<A, B>(a, b); }
template <class A>
struct PumpItemArray : public Pump::Item
{
PumpItemArray(A& a, ArrayCtrl& array, int row, int column) : a(a), array(array), row(row), column(column) {}
virtual void Run(bool write)
{
if(write) { a = array.Get(row, column); }
else { array.Set(row, column, a); }
}
A& a;
ArrayCtrl& array;
int row;
int column;
};
template <class A, class B>
struct PumpItemScaledData : public Pump::Item
{
PumpItemScaledData(A& a, B& b, double scale) : a(a), b(b), scale(scale) {}
virtual void Run(bool write)
{
if(write) { double d = ~b; a = (IsNull(d) ? d : d * scale); }
else { b <<= (IsNull(a) ? double(Null) : (double)a / scale); }
}
A& a;
B& b;
double scale;
};
template <class A, class B>
struct PumpItemIntScaledData : public Pump::Item
{
PumpItemIntScaledData(A& a, B& b, double scale) : a(a), b(b), scale(scale) {}
virtual void Run(bool write)
{
if(write) { double d = ~b; a = (IsNull(d) ? (int)Null : fround(d * scale)); }
else { b <<= (IsNull(a) ? double(Null) : (double)a / scale); }
}
A& a;
B& b;
double scale;
};
template <class A, class B>
One<Pump::Item> PumpScaledData(A& a, B& b, double scale) { return new PumpItemScaledData<A, B>(a, b, scale); }
template <class A, class B>
One<Pump::Item> PumpAngleData(A& a, B& b) { return PumpScaledData<A, B>(a, b, M_PI / 180.0); }
template <class A, class B>
One<Pump::Item> PumpIntScaledData(A& a, B& b, double scale) { return new PumpItemIntScaledData<A, B>(a, b, scale); }
template <class A, class B>
One<Pump::Item> PumpIntAngleData(A& a, B& b) { return PumpIntScaledData<A, B>(a, b, M_PI / 180.0); }
template <class A>
inline One<Pump::Item> PumpArray(A& a, ArrayCtrl& array, int row, int column)
{ return new PumpItemArray<A>(a, array, row, column); }
template <class A>
inline One<Pump::Item> PumpArray(A& a, ArrayCtrl& array, int row, Id column)
{ return new PumpItemArray<A>(a, array, row, array.GetPos(column)); }
template <class A, class C>
struct PumpItemArrayCast : public Pump::Item
{
PumpItemArrayCast(A& a, ArrayCtrl& array, int row, int column) : a(a), array(array), row(row), column(column) {}
virtual void Run(bool write)
{
if(write) { a = A(C(array.Get(row, column))); }
else { array.Set(row, column, (C)a); }
}
A& a;
ArrayCtrl& array;
int row;
int column;
};
template <class C, class A>
inline One<Pump::Item> PumpArrayCast(A& a, ArrayCtrl& array, int row, int column)
{ return new PumpItemArrayCast<A, C>(a, array, row, column); }
template <class C, class A>
inline One<Pump::Item> PumpArrayCast(A& a, ArrayCtrl& array, int row, Id column)
{ return new PumpItemArrayCast<A, C>(a, array, row, array.GetPos(column)); }
struct PumpItemArrayRef : public Pump::Item
{
PumpItemArrayRef(Ref ref, ArrayCtrl& array, int row, int column)
: ref(ref), array(array), row(row), column(column) {}
virtual void Run(bool write)
{
if(write) { ref.SetValue(array.Get(row, column)); }
else { array.Set(row, column, Value(ref)); }
}
Ref ref;
ArrayCtrl& array;
int row;
int column;
};
inline One<Pump::Item> PumpArrayRef(Ref ref, ArrayCtrl& array, int row, int column)
{ return new PumpItemArrayRef(ref, array, row, column); }
inline One<Pump::Item> PumpArrayRef(Ref ref, ArrayCtrl& array, int row, Id column)
{ return new PumpItemArrayRef(ref, array, row, array.GetPos(column)); }
bool IsUnique(const ArrayCtrl& table, int column);
bool IsUnique(const ArrayCtrl& table, Id column);
int SwapRows(ArrayCtrl& table, int row1, int row2);
void SetColumn(ArrayCtrl& table, int index, const Value& value);
void SetColumn(ArrayCtrl& table, Id column, const Value& value);
Index<int> GetSelIndex(const ArrayCtrl& table);
BorderFrame& TopJoinFrame();
BorderFrame& BottomJoinFrame();
class TabPageCtrl : public StaticRect {
public:
TabPageCtrl() { Transparent(); Color(Null); /*Blend(SColorFace(), SColorPaper()));*/ }
};
class DropListAll : public DropList
{
public:
DropListAll() { DisplayAll(); }
};
class DropButton : public FrameRight<Button>
{
public:
DropButton();
virtual bool HotKey(dword key);
public:
Gate1<dword> WhenHotKey;
};
class ChoiceList : public PopUpTable
{
public:
typedef ChoiceList CLASSNAME;
ChoiceList();
ChoiceList& Attach(Ctrl& owner);
void Detach();
ChoiceList& operator >> (Ctrl& owner) { return Attach(owner); }
void OnDrop();
void OnToggle();
void OnSelect();
void OnCancel();
ChoiceList& DropWidth(int _wd) { dropbutton.Width(_wd); return *this; }
ChoiceList& DropShow(bool ds) { dropbutton.Show(ds); return *this; }
ChoiceList& DataItem(int _item) { item = _item; return *this; }
ChoiceList& DataItem(Id _col_id) { item = GetPos(_col_id); return *this; }
int GetDataItem() const { return item; }
bool OnKey(dword key);
public:
Callback WhenDrop;
protected:
void Initialize();
protected:
DropButton dropbutton;
Ctrl *owner;
int item;
};
class ExtendedButton : public FrameRight<Button>
{
public:
ExtendedButton();
virtual bool HotKey(dword key);
};
class ExtendedFileButton : public FrameRight<Button>
{
public:
ExtendedFileButton();
virtual bool HotKey(dword key);
};
class MenuButton : public ExtendedButton
{
public:
MenuButton();
Callback1<Bar&> WhenBar;
private:
void OnMenu();
};
//////////////////////////////////////////////////////////////////////
// DragDropCtrl::
class DragDropCtrl : public Ctrl
{
public:
DragDropCtrl();
virtual ~DragDropCtrl();
// drag & drop interface
virtual bool Push(Point pt, dword keyflags);
virtual void Drag(Point pt, Point last, Point next, dword keyflags);
virtual void Drop(Point pt, Point end, dword keyflags);
virtual void Click(Point pt, dword keyflags);
virtual void Cancel();
virtual void DragRect(const Rect& last, const Rect& next, dword keyflags);
virtual void DropRect(const Rect& rc, dword keyflags);
void DragShow(bool _show = true);
void DragHide() { DragShow(false); }
void DragStop(bool accept, dword keyflags);
void DragStop(bool accept = false) { DragStop(accept, last_key); }
bool IsDragging() const { return state == ON || state == HIDDEN; }
bool IsPushed() const { return state != OFF; }
// control overrides
virtual void LeftDown(Point pt, dword keyflags);
virtual void LeftDouble(Point pt, dword keyflags);
virtual void LeftUp(Point pt, dword keyflags);
virtual void RightDown(Point pt, dword keyflags);
virtual void RightDouble(Point pt, dword keyflags);
virtual void RightUp(Point pt, dword keyflags);
virtual void MouseMove(Point pt, dword keyflags);
virtual bool Key(dword key, int repcnt);
private:
Point start, last;
dword last_key;
char state;
enum { OFF, ON, POSSIBLE, HIDDEN };
};
class StdArrayOrder : public ArrayCtrl::Order
{
public:
StdArrayOrder() {}
StdArrayOrder(int i, bool d = false, dword l = 0) { Add(i, d, l); }
void Clear() { index.Clear(); desc.Clear(); lang.Clear(); }
void Add(int i, bool d = false, dword l = 0) { index.Add(i); desc.Add(d); lang.Add(l); }
void Set(int i, bool d = false, dword l = 0) { Clear(); Add(i, d, l); }
virtual bool operator () (const Vector<Value>& row1, const Vector<Value>& row2) const;
private:
Vector<int> index;
Vector<bool> desc;
Vector<dword> lang;
};
class ArrayPair : public Ctrl
{
public:
typedef ArrayPair CLASSNAME;
ArrayPair();
ArrayPair& RowName(const char *s) { left.RowName(s); right.RowName(s); return *this; }
ArrayPair& AppendLine(bool b = true) { left.AppendLine(b); right.AppendLine(b); return *this; }
ArrayPair& NoAppendLine() { return AppendLine(false); }
ArrayPair& Inserting(bool b = true) { left.Inserting(b); right.Inserting(b); return AppendLine(b); }
ArrayPair& NoInserting() { return Inserting(false); }
ArrayPair& Removing(bool b = true) { left.Removing(b); right.Removing(b); return *this; }
ArrayPair& NoRemoving() { return Removing(false); }
ArrayPair& Appending(bool b = true) { left.Appending(b); right.Appending(b); return *this; }
ArrayPair& BeforeAfterInserting(int q = 1) { left.BeforeAfterInserting(q); right.BeforeAfterInserting(q); return *this; }
ArrayPair& AfterBeforeInserting(int q = 2) { left.AfterBeforeInserting(q); right.AfterBeforeInserting(q); return *this; }
ArrayPair& Duplicating(bool b = true) { left.Duplicating(b); right.Duplicating(b); return *this; }
ArrayPair& NoInsertAppend(bool b = true) { left.NoInsertAppend(b); right.NoInsertAppend(b); return *this; }
ArrayPair& Moving(bool b = true) { left.Moving(b); right.Moving(b); return *this; }
ArrayPair& NoDuplicating() { return Duplicating(false); }
ArrayPair& AskRemove(bool b = true) { left.AskRemove(b); right.AskRemove(b); return *this; }
ArrayPair& NoAskRemove() { return AskRemove(false); }
ArrayPair& Header(bool b = true) { left.Header(b); right.Header(b); return *this; }
ArrayPair& NoHeader() { return Header(false); }
ArrayPair& Track(bool b = true) { left.Track(b); right.Track(b); return *this; }
ArrayPair& NoTrack() { return Track(false); }
ArrayPair& VertGrid(bool b = true) { left.VertGrid(b); right.VertGrid(b); return *this; }
ArrayPair& NoVertGrid() { return VertGrid(false); }
ArrayPair& HorzGrid(bool b = true) { left.HorzGrid(b); right.HorzGrid(b); return *this; }
ArrayPair& NoHorzGrid() { return HorzGrid(false); }
ArrayPair& Grid(bool b = true) { return VertGrid(b).HorzGrid(b); }
ArrayPair& NoGrid() { return Grid(false); }
ArrayPair& GridColor(Color c) { left.GridColor(c); right.GridColor(c); return *this; }
ArrayPair& NoCursor(bool b = true) { left.NoCursor(b); right.NoCursor(b); return *this; }
ArrayPair& MouseMoveCursor(bool b = true) { left.MouseMoveCursor(b); right.MouseMoveCursor(b); return *this; }
ArrayPair& NoMouseMoveCursor() { return MouseMoveCursor(false); }
ArrayPair& AutoHideSb(bool b = true) { left.AutoHideSb(b); right.AutoHideSb(); return *this; }
ArrayPair& NoAutoHideSb() { return AutoHideSb(false); }
ArrayPair& MultiSelect(bool b = true) { left.MultiSelect(b); right.MultiSelect(b); return *this; }
ArrayPair& Vert(bool vert = true);
ArrayPair& Horz() { return Vert(false); }
bool IsVert() const { return is_vert; }
void SetPos(int pos);
void HalfPos() { SetPos(5000); }
int GetPos() const { return pane_pos; }
virtual void Layout();
virtual void SetData(const Value& value);
virtual Value GetData() const;
void SetKey(int i);
void SetKey(Id id);
int GetKey() const { return key_index; }
void SetSort(int i, const ArrayCtrl::Order& order);
void SetSort(Id id, const ArrayCtrl::Order& order) { SetSort(left.GetPos(id), order); }
void SetSort(int i);
void SetSort(Id id) { SetSort(left.GetPos(id)); }
void NoSort() { SetSort(-1, std_order); }
void UpdateGUI();
TOOL(Left)
TOOL(Add)
TOOL(AddAll)
TOOL(Right)
TOOL(Remove)
TOOL(RemoveAll)
public:
Callback WhenAdd;
ArrayCtrl left, right;
private:
void OnRightCursor();
void SortLeft();
void SortRight();
private:
Button add, add_all, remove, remove_all;
int key_index;
int sort_index;
int pane_pos;
bool is_vert;
const ArrayCtrl::Order *order;
StdArrayOrder std_order;
};
template <class T>
Vector<T> GetArrayColumn(const ArrayCtrl& array, int column)
{
Vector<T> out;
out.SetCount(array.GetCount());
for(int i = 0; i < out.GetCount(); i++)
out[i] = array.Get(i, column);
return out;
}
template <class T>
Vector<T> GetKeyVector(const ArrayPair& pair)
{
ASSERT(pair.GetKey() >= 0);
return GetArrayColumn<T>(pair.right, pair.GetKey());
}
template <class C>
void SetKeyContainer(ArrayPair& pair, const C& container)
{
typedef typename C::ConstIterator CI;
int k = pair.GetKey();
ASSERT(k >= 0);
for(CI b = container.Begin(), e = container.End(); b != e; ++b)
if(pair.left.FindSetCursor(*b, k))
pair.OnAdd();
if(pair.left.GetCount() > 0)
pair.left.SetCursor(0);
if(pair.right.GetCount() > 0)
pair.right.SetCursor(0);
}
class ValueArrayCtrl : public ArrayCtrl
{
public:
typedef ValueArrayCtrl CLASSNAME;
ValueArrayCtrl();
virtual void SetData(const Value& data);
virtual Value GetData() const;
virtual bool Accept();
public:
Callback WhenSetData;
Gate WhenAccept;
private:
void OnArrayAction();
};
class CallbackDataCtrl : public Ctrl {
public:
CallbackDataCtrl() { NoWantFocus(); }
virtual void SetData(const Value& v) { WhenSetData(v); }
virtual Value GetData() const { Value v; WhenGetData(v); return v; }
virtual bool Key(dword key, int repcnt) { return WhenKey(key) || Ctrl::Key(key, repcnt); }
public:
Callback1<const Value&> WhenSetData;
Callback1<Value&> WhenGetData;
Gate1<dword> WhenKey;
};
//////////////////////////////////////////////////////////////////////
// Option3::
/*
class Option3 : public Pusher
{
public:
Option3();
operator bool() const { return state == 1; }
void operator = (bool b) { state = b ? 1 : 0; }
Option3& NotNull(bool nn) { not_null = nn; return *this; }
Option3& NoNotNull() { return NotNull(false); }
virtual void Paint(Draw& draw);
virtual Size GetMinSize() const;
virtual void SetData(const Value& data);
virtual Value GetData() const; // Null = indeterminate
protected:
virtual void RefreshPush();
virtual void RefreshFocus();
virtual void PerformAction();
protected:
char state; // 2 = indeterminate
bool not_null;
};
*/
#ifdef PLATFORM_WIN32
void DropFilesRegister(HWND hwnd);
Point DropFilesGetPos(WPARAM hdrop);
Vector<String> DropFilesGetList(WPARAM hdrop);
#endif
bool ShowErrorFocus(bool cond, const char *text, Ctrl& focus);
}