mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
gui_sizeof merged, double formatting precsion in JSON/XML reduced to 15 digits
This commit is contained in:
commit
0449296f07
93 changed files with 3268 additions and 1789 deletions
10
autotest/CtrlChildren/CtrlChildren.upp
Normal file
10
autotest/CtrlChildren/CtrlChildren.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
etalon.log,
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
15
autotest/CtrlChildren/etalon.log
Normal file
15
autotest/CtrlChildren/etalon.log
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
* C:\upp\out\gui_sizeof_autotest\CLANGx64.Debug.Debug_Full.Gui\CtrlChildren.exe 12.04.2022 11:30:36, user: cxl
|
||||
|
||||
==============================
|
||||
N3Upp5LabelE
|
||||
N3Upp10EditMinMaxIiNS_10ConvertIntEEE
|
||||
==============================
|
||||
N3Upp5LabelE
|
||||
N3Upp10StaticRectE
|
||||
N3Upp10EditMinMaxIiNS_10ConvertIntEEE
|
||||
==============================
|
||||
N3Upp10StaticRectE
|
||||
N3Upp10EditMinMaxIiNS_10ConvertIntEEE
|
||||
==============================
|
||||
N3Upp10StaticRectE
|
||||
==============================
|
||||
29
autotest/CtrlChildren/main.cpp
Normal file
29
autotest/CtrlChildren/main.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
TopWindow top;
|
||||
Label lbl;
|
||||
EditInt edit;
|
||||
StaticRect list;
|
||||
auto Print = [&] {
|
||||
DLOG("==============================");
|
||||
for(Ctrl& q : top)
|
||||
DLOG(typeid(q).name());
|
||||
};
|
||||
|
||||
top << lbl << edit;
|
||||
Print();
|
||||
top.AddChild(&list, &lbl);
|
||||
Print();
|
||||
lbl.Remove();
|
||||
Print();
|
||||
edit.Ctrl::Remove();
|
||||
Print();
|
||||
list.Ctrl::Remove();
|
||||
Print();
|
||||
|
||||
CheckLogEtalon();
|
||||
}
|
||||
9
autotest/CtrlFrame/CtrlFrame.upp
Normal file
9
autotest/CtrlFrame/CtrlFrame.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
53
autotest/CtrlFrame/main.cpp
Normal file
53
autotest/CtrlFrame/main.cpp
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
NullFrameClass fr[50];
|
||||
for(int q = 0; q < 10000; q++) {
|
||||
DLOG("==========");
|
||||
Ctrl h;
|
||||
Vector<CtrlFrame *> h1;
|
||||
int N = Random(40) + 1;
|
||||
h1.Add(&NullFrame());
|
||||
for(int i = 0; i < N; i++) {
|
||||
int pos = Random(h.GetFrameCount() + 1);
|
||||
CtrlFrame& val = fr[Random(50)];
|
||||
h.InsertFrame(pos, val);
|
||||
h1.Insert(pos, &val);
|
||||
DDUMP(h.GetFrameCount());
|
||||
DDUMP(h1.GetCount());
|
||||
ASSERT(h1.GetCount() == h.GetFrameCount());
|
||||
for(int i = 0; i < h.GetFrameCount(); i++)
|
||||
ASSERT(&h.GetFrame(i) == h1[i]);
|
||||
#if 0
|
||||
DLOG("===========");
|
||||
DDUMP(pos);
|
||||
DDUMP(val);
|
||||
DDUMP(h.GetFrameCount());
|
||||
for(int i = 0; i < h.GetFrameCount(); i++)
|
||||
DLOG(i << " " << h.GetFrame(i));
|
||||
#endif
|
||||
}
|
||||
while(h.GetFrameCount() > 1) {
|
||||
int pos = Random(h.GetFrameCount());
|
||||
h.RemoveFrame(pos);
|
||||
h1.Remove(pos);
|
||||
DDUMP(h.GetFrameCount());
|
||||
DDUMP(h1.GetCount());
|
||||
ASSERT(h1.GetCount() == h.GetFrameCount());
|
||||
for(int i = 0; i < h.GetFrameCount(); i++)
|
||||
ASSERT(&h.GetFrame(i) == h1[i]);
|
||||
#if 0
|
||||
DLOG("===========");
|
||||
DDUMP(pos);
|
||||
DDUMP(h.GetFrameCount());
|
||||
for(int i = 0; i < h.GetFrameCount(); i++)
|
||||
DLOG(i << " " << h.GetFrame(i));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DLOG("================ OK");
|
||||
}
|
||||
10
autotest/CtrlInfoParts/CtrlInfoParts.upp
Normal file
10
autotest/CtrlInfoParts/CtrlInfoParts.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
CtrlLib;
|
||||
|
||||
file
|
||||
etalon.log,
|
||||
main.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "GUI";
|
||||
|
||||
27
autotest/CtrlInfoParts/etalon.log
Normal file
27
autotest/CtrlInfoParts/etalon.log
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
* C:\upp\out\gui_sizeof_autotest\CLANGx64.Debug.Debug_Full.Gui\CtrlInfoParts.exe 11.04.2022 18:41:30, user: cxl
|
||||
|
||||
========================
|
||||
h.GetLayoutId() = just some literal
|
||||
h.GetTip() =
|
||||
h.GetDescription() =
|
||||
h.GetHelpLine() =
|
||||
========================
|
||||
h.GetLayoutId() = just some text
|
||||
h.GetTip() =
|
||||
h.GetDescription() =
|
||||
h.GetHelpLine() =
|
||||
========================
|
||||
h.GetLayoutId() = just some literal
|
||||
h.GetTip() =
|
||||
h.GetDescription() =
|
||||
h.GetHelpLine() = some helpline
|
||||
========================
|
||||
h.GetLayoutId() = just some text
|
||||
h.GetTip() =
|
||||
h.GetDescription() =
|
||||
h.GetHelpLine() = some helpline
|
||||
========================
|
||||
h.GetLayoutId() = just some literal
|
||||
h.GetTip() = this is tip
|
||||
h.GetDescription() = this is description
|
||||
h.GetHelpLine() = some helpline
|
||||
51
autotest/CtrlInfoParts/main.cpp
Normal file
51
autotest/CtrlInfoParts/main.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <CtrlLib/CtrlLib.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
auto Print = [&](Ctrl& h) {
|
||||
DLOG("========================");
|
||||
DDUMP(h.GetLayoutId());
|
||||
DDUMP(h.GetTip());
|
||||
DDUMP(h.GetDescription());
|
||||
DDUMP(h.GetHelpLine());
|
||||
};
|
||||
|
||||
{
|
||||
Ctrl h;
|
||||
h.LayoutIdLiteral("just some literal");
|
||||
Print(h);
|
||||
}
|
||||
|
||||
{
|
||||
Ctrl h;
|
||||
h.LayoutId(String("just some text"));
|
||||
Print(h);
|
||||
}
|
||||
|
||||
{
|
||||
Ctrl h;
|
||||
h.LayoutIdLiteral("just some literal");
|
||||
h.HelpLine("some helpline");
|
||||
Print(h);
|
||||
}
|
||||
|
||||
{
|
||||
Ctrl h;
|
||||
h.LayoutId(String("just some text"));
|
||||
h.HelpLine("some helpline");
|
||||
Print(h);
|
||||
}
|
||||
|
||||
{
|
||||
Ctrl h;
|
||||
h.LayoutIdLiteral("just some literal");
|
||||
h.Tip("this is tip");
|
||||
h.HelpLine("some helpline");
|
||||
h.Description("this is description");
|
||||
Print(h);
|
||||
}
|
||||
|
||||
CheckLogEtalon();
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@ GUI_APP_MAIN
|
|||
RDUMP(sizeof(EditIntSpin));
|
||||
RDUMP(sizeof(DisplayPopup));
|
||||
RDUMP(sizeof(PopUpTable));
|
||||
RDUMP(sizeof(WithDropChoice<EditString>));
|
||||
RDUMP(sizeof(DropList));
|
||||
RDUMP(sizeof(WithDropChoice<EditString>));
|
||||
RDUMP(sizeof(ArrayCtrl));
|
||||
RDUMP(sizeof(TreeCtrl));
|
||||
RDUMP(sizeof(TreeCtrl::Node));
|
||||
|
|
|
|||
|
|
@ -95,12 +95,14 @@ file
|
|||
Algo.h,
|
||||
CoAlgo.h,
|
||||
Sorted.h,
|
||||
Sort.h,
|
||||
CoSort.h,
|
||||
Obsolete.h,
|
||||
Sort.h,
|
||||
Vcont.h,
|
||||
BiCont.h,
|
||||
Other.h,
|
||||
Other.hpp,
|
||||
PackedData.cpp,
|
||||
Vcont.hpp,
|
||||
Vcont.cpp,
|
||||
Index.h,
|
||||
|
|
|
|||
|
|
@ -343,15 +343,19 @@ void Index<T>::Serialize(Stream& s)
|
|||
h.Serialize(s);
|
||||
if(s.IsLoading())
|
||||
for(int i = 0; i < h.GetCount(); i++)
|
||||
if(h[i] & 0x80000000)
|
||||
if(i < GetCount() && h[i] & 0x80000000)
|
||||
Unlink(i);
|
||||
}
|
||||
else {
|
||||
Vector<int> u = GetUnlinked();
|
||||
u.Serialize(s);
|
||||
if(s.IsLoading())
|
||||
for(int i : ReverseRange(u)) // Reverse range to ensure the correct order of Put
|
||||
Unlink(i);
|
||||
for(int i : ReverseRange(u)) { // Reverse range to ensure the correct order of Put
|
||||
if(i >= 0 && i < GetCount())
|
||||
Unlink(i);
|
||||
else
|
||||
s.LoadError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ String AsJSON(const Value& v, const String& sep, bool pretty)
|
|||
if(v.GetType() == BOOL_V)
|
||||
return (bool)v ? "true" : "false";
|
||||
if(IsNumber(v))
|
||||
return FormatG((double)v, 17);
|
||||
return FormatG((double)v, 15);
|
||||
if(IsString(v))
|
||||
return AsCString((String)v, INT_MAX, NULL, ASCSTRING_JSON);
|
||||
if(IsDateTime(v))
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ template <class K, class T, class V>
|
|||
void AMap<K, T, V>::Serialize(Stream& s) {
|
||||
int version = 0;
|
||||
s / version % key % value;
|
||||
if(key.GetCount() != value.GetCount())
|
||||
s.LoadError();
|
||||
}
|
||||
|
||||
template <class K, class T, class V>
|
||||
|
|
@ -167,6 +169,8 @@ void AMap<K, T, V>::Sweep()
|
|||
template <class K, class T, class V, class Less>
|
||||
void FixedAMap<K, T, V, Less>::Serialize(Stream& s) {
|
||||
s % key % value;
|
||||
if(key.GetCount() != value.GetCount())
|
||||
s.LoadError();
|
||||
}
|
||||
|
||||
template <class K, class T, class V, class Less>
|
||||
|
|
|
|||
|
|
@ -103,117 +103,50 @@ public:
|
|||
void operator=(const Bits&) = delete;
|
||||
};
|
||||
|
||||
//# System dependent
|
||||
template <class T>
|
||||
class Mitor : Moveable< Mitor<T> > {
|
||||
union {
|
||||
mutable unsigned count;
|
||||
mutable Vector<T> *vector;
|
||||
};
|
||||
byte elem0[sizeof(T)];
|
||||
|
||||
T& Get(int i) const;
|
||||
void Pick(Mitor&& m);
|
||||
void Copy(const Mitor& m);
|
||||
void Chk() const { ASSERT(count != 2); }
|
||||
class PackedData {
|
||||
void *ptr = nullptr;
|
||||
|
||||
template <class T>
|
||||
T Get(int ii, T def) const;
|
||||
|
||||
public:
|
||||
T& operator[](int i) { return Get(i); }
|
||||
const T& operator[](int i) const { return Get(i); }
|
||||
int GetCount() const;
|
||||
T& Add();
|
||||
void Add(const T& x);
|
||||
void Clear();
|
||||
void Shrink();
|
||||
void SetRawPtr(void *p) { ptr = p; }
|
||||
void *GetRawPtr() const { return ptr; }
|
||||
|
||||
Mitor(Mitor&& m) { Pick(pick(m)); }
|
||||
void operator=(Mitor&& m) { if(this != &m) { Clear(); Pick(pick(m)); } }
|
||||
void SetData(int ii, const void *data, int datalen);
|
||||
|
||||
Mitor(Mitor& m, int) { Copy(m); }
|
||||
template <class F>
|
||||
bool GetData(int ii, F out) const;
|
||||
|
||||
void SetNull(int ii) { SetData(ii, NULL, 0); }
|
||||
|
||||
Mitor() { count = 0; }
|
||||
~Mitor() { Clear(); }
|
||||
void SetString(int ii, const char *s) { SetData(ii, s, strlen(s)); }
|
||||
void SetString(int ii, const String& s) { SetData(ii, s, s.GetCount()); }
|
||||
String GetString(int ii) const { String r; GetData(ii, [&](const char *s, int n) { r = String(s, n); }); return r; }
|
||||
|
||||
void SetInt(int ii, int val) { SetData(ii, &val, sizeof(int)); }
|
||||
int GetInt(int ii, int def) const { return Get<int>(ii, def); }
|
||||
|
||||
void SetDword(int ii, dword val) { SetData(ii, &val, sizeof(dword)); }
|
||||
int GetDword(int ii, dword def) const { return Get<dword>(ii, def); }
|
||||
|
||||
void SetInt64(int ii, int64 val) { SetData(ii, &val, sizeof(int64)); }
|
||||
int64 GetInt64(int ii, int64 def) const { return Get<int64>(ii, def); }
|
||||
|
||||
void SetPtr(int ii, void *val) { SetData(ii, &val, sizeof(void *)); }
|
||||
void *GetPtr(int ii) const { return Get<void *>(ii, nullptr); }
|
||||
|
||||
void Clear();
|
||||
|
||||
Vector<String> Unpack() const;
|
||||
size_t GetPackedSize() const;
|
||||
String GetPacked() const { return String((const char *)ptr, GetPackedSize()); }
|
||||
|
||||
PackedData() {}
|
||||
PackedData(const PackedData&) = delete;
|
||||
~PackedData();
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T& Mitor<T>::Get(int i) const
|
||||
{
|
||||
ASSERT(i >= 0 && i < GetCount());
|
||||
return i == 0 ? *(T*)elem0 : (*const_cast<Vector<T>*>(vector))[i - 1];
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Mitor<T>::Pick(Mitor&& m)
|
||||
{
|
||||
m.Chk();
|
||||
vector = m.vector;
|
||||
memcpy(&elem0, &m.elem0, sizeof(T));
|
||||
m.count = 2;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Mitor<T>::Copy(const Mitor& m)
|
||||
{
|
||||
m.Chk();
|
||||
if(m.count > 0)
|
||||
DeepCopyConstruct(elem0, (const T*)m.elem0);
|
||||
if(m.count > 1)
|
||||
vector = new Vector<T>(*m.vector, 1);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
int Mitor<T>::GetCount() const
|
||||
{
|
||||
Chk();
|
||||
return count > 1 ? vector->GetCount() + 1 : count;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T& Mitor<T>::Add()
|
||||
{
|
||||
Chk();
|
||||
if(count == 0) {
|
||||
count = 1;
|
||||
return *new(elem0) T;
|
||||
}
|
||||
if(count == 1)
|
||||
vector = new Vector<T>;
|
||||
return vector->Add();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Mitor<T>::Add(const T& x)
|
||||
{
|
||||
Chk();
|
||||
if(count == 0) {
|
||||
count = 1;
|
||||
new((T*) elem0) T(x);
|
||||
}
|
||||
else {
|
||||
if(count == 1)
|
||||
vector = new Vector<T>;
|
||||
vector->Add(x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Mitor<T>::Clear()
|
||||
{
|
||||
if(count > 2)
|
||||
delete vector;
|
||||
if(count && count != 2)
|
||||
((T*)elem0)->~T();
|
||||
count = 0;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void Mitor<T>::Shrink()
|
||||
{
|
||||
if(count > 2)
|
||||
vector->Shrink();
|
||||
}
|
||||
|
||||
//#
|
||||
template <class T, int N = 1>
|
||||
struct Link {
|
||||
T *link_prev[N];
|
||||
|
|
@ -336,169 +269,4 @@ public:
|
|||
LRUCache() { head = -1; size = 0; count = 0; ClearCounters(); }
|
||||
};
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::LinkHead(int i)
|
||||
{
|
||||
Item& m = data[i];
|
||||
if(head >= 0) {
|
||||
int tail = data[head].prev;
|
||||
m.next = head;
|
||||
m.prev = tail;
|
||||
data[head].prev = i;
|
||||
data[tail].next = i;
|
||||
}
|
||||
else
|
||||
m.prev = m.next = i;
|
||||
head = i;
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Unlink(int i)
|
||||
{
|
||||
Item& m = data[i];
|
||||
if(m.prev == i)
|
||||
head = -1;
|
||||
else {
|
||||
if(head == i)
|
||||
head = m.next;
|
||||
data[m.next].prev = m.prev;
|
||||
data[m.prev].next = m.next;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
T& LRUCache<T, K>::GetLRU()
|
||||
{
|
||||
int tail = data[head].prev;
|
||||
return *data[tail].data;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
const K& LRUCache<T, K>::GetLRUKey()
|
||||
{
|
||||
int tail = data[head].prev;
|
||||
return key[tail].key;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::DropLRU()
|
||||
{
|
||||
if(head >= 0) {
|
||||
int tail = data[head].prev;
|
||||
size -= data[tail].size;
|
||||
data[tail].data.Clear();
|
||||
Unlink(tail);
|
||||
key.Unlink(tail);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
void LRUCache<T, K>::AdjustSize(P getsize)
|
||||
{
|
||||
size = 0;
|
||||
count = 0;
|
||||
for(int i = 0; i < data.GetCount(); i++)
|
||||
if(!key.IsUnlinked(i)) {
|
||||
int sz = getsize(*data[i].data);
|
||||
if(sz >= 0)
|
||||
data[i].size = sz + InternalSize;
|
||||
size += data[i].size;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
int LRUCache<T, K>::Remove(P predicate)
|
||||
{
|
||||
int n = 0;
|
||||
int i = 0;
|
||||
while(i < data.GetCount())
|
||||
if(!key.IsUnlinked(i) && predicate(*data[i].data)) {
|
||||
size -= data[i].size;
|
||||
Unlink(i);
|
||||
key.Unlink(i);
|
||||
n++;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
bool LRUCache<T, K>::RemoveOne(P predicate)
|
||||
{
|
||||
int i = head;
|
||||
if(i >= 0)
|
||||
for(;;) {
|
||||
int next = data[i].next;
|
||||
if(predicate(*data[i].data)) {
|
||||
size -= data[i].size;
|
||||
Unlink(i);
|
||||
key.Unlink(i);
|
||||
return true;
|
||||
}
|
||||
if(i == next || next == head || next < 0)
|
||||
break;
|
||||
i = next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Shrink(int maxsize, int maxcount)
|
||||
{
|
||||
if(maxsize >= 0 && maxcount >= 0)
|
||||
while(count > maxcount || size > maxsize)
|
||||
DropLRU();
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Clear()
|
||||
{
|
||||
head = -1;
|
||||
size = 0;
|
||||
count = 0;
|
||||
newsize = foundsize = 0;
|
||||
key.Clear();
|
||||
data.Clear();
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::ClearCounters()
|
||||
{
|
||||
flag = !flag;
|
||||
newsize = foundsize = 0;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
T& LRUCache<T, K>::Get(const Maker& m)
|
||||
{
|
||||
Key k;
|
||||
k.key = m.Key();
|
||||
k.type = typeid(m).name();
|
||||
int q = key.Find(k);
|
||||
if(q < 0) {
|
||||
q = key.Put(k);
|
||||
Item& t = data.At(q);
|
||||
t.size = m.Make(t.data.Create()) + InternalSize;
|
||||
size += t.size;
|
||||
newsize += t.size;
|
||||
t.flag = flag;
|
||||
}
|
||||
else {
|
||||
Item& t = data[q];
|
||||
Unlink(q);
|
||||
if(t.flag != flag) {
|
||||
t.flag = flag;
|
||||
foundsize += t.size;
|
||||
}
|
||||
}
|
||||
LinkHead(q);
|
||||
return *data[q].data;
|
||||
}
|
||||
#include "Other.hpp"
|
||||
|
|
|
|||
204
uppsrc/Core/Other.hpp
Normal file
204
uppsrc/Core/Other.hpp
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
template <class F>
|
||||
bool PackedData::GetData(int ii, F out) const
|
||||
{
|
||||
int i = 0;
|
||||
const byte *s = (const byte *)ptr;
|
||||
if(s)
|
||||
for(;;) {
|
||||
int len = *s++;
|
||||
if(len == 255)
|
||||
break;
|
||||
if(len == 254) {
|
||||
memcpy(&len, s, 4);
|
||||
s += 4;
|
||||
}
|
||||
if(i == ii) {
|
||||
out((const char *)s, len);
|
||||
return true;
|
||||
}
|
||||
s += len;
|
||||
i++;
|
||||
}
|
||||
out("", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T PackedData::Get(int ii, T def) const
|
||||
{
|
||||
T q = def;
|
||||
GetData(ii, [&](const char *ptr, int len) {
|
||||
if(len) {
|
||||
ASSERT(len == sizeof(T));
|
||||
memcpy(&q, ptr, sizeof(T));
|
||||
}
|
||||
});
|
||||
return q;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::LinkHead(int i)
|
||||
{
|
||||
Item& m = data[i];
|
||||
if(head >= 0) {
|
||||
int tail = data[head].prev;
|
||||
m.next = head;
|
||||
m.prev = tail;
|
||||
data[head].prev = i;
|
||||
data[tail].next = i;
|
||||
}
|
||||
else
|
||||
m.prev = m.next = i;
|
||||
head = i;
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Unlink(int i)
|
||||
{
|
||||
Item& m = data[i];
|
||||
if(m.prev == i)
|
||||
head = -1;
|
||||
else {
|
||||
if(head == i)
|
||||
head = m.next;
|
||||
data[m.next].prev = m.prev;
|
||||
data[m.prev].next = m.next;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
T& LRUCache<T, K>::GetLRU()
|
||||
{
|
||||
int tail = data[head].prev;
|
||||
return *data[tail].data;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
const K& LRUCache<T, K>::GetLRUKey()
|
||||
{
|
||||
int tail = data[head].prev;
|
||||
return key[tail].key;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::DropLRU()
|
||||
{
|
||||
if(head >= 0) {
|
||||
int tail = data[head].prev;
|
||||
size -= data[tail].size;
|
||||
data[tail].data.Clear();
|
||||
Unlink(tail);
|
||||
key.Unlink(tail);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
void LRUCache<T, K>::AdjustSize(P getsize)
|
||||
{
|
||||
size = 0;
|
||||
count = 0;
|
||||
for(int i = 0; i < data.GetCount(); i++)
|
||||
if(!key.IsUnlinked(i)) {
|
||||
int sz = getsize(*data[i].data);
|
||||
if(sz >= 0)
|
||||
data[i].size = sz + InternalSize;
|
||||
size += data[i].size;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
int LRUCache<T, K>::Remove(P predicate)
|
||||
{
|
||||
int n = 0;
|
||||
int i = 0;
|
||||
while(i < data.GetCount())
|
||||
if(!key.IsUnlinked(i) && predicate(*data[i].data)) {
|
||||
size -= data[i].size;
|
||||
Unlink(i);
|
||||
key.Unlink(i);
|
||||
n++;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
template <class P>
|
||||
bool LRUCache<T, K>::RemoveOne(P predicate)
|
||||
{
|
||||
int i = head;
|
||||
if(i >= 0)
|
||||
for(;;) {
|
||||
int next = data[i].next;
|
||||
if(predicate(*data[i].data)) {
|
||||
size -= data[i].size;
|
||||
Unlink(i);
|
||||
key.Unlink(i);
|
||||
return true;
|
||||
}
|
||||
if(i == next || next == head || next < 0)
|
||||
break;
|
||||
i = next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Shrink(int maxsize, int maxcount)
|
||||
{
|
||||
if(maxsize >= 0 && maxcount >= 0)
|
||||
while(count > maxcount || size > maxsize)
|
||||
DropLRU();
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::Clear()
|
||||
{
|
||||
head = -1;
|
||||
size = 0;
|
||||
count = 0;
|
||||
newsize = foundsize = 0;
|
||||
key.Clear();
|
||||
data.Clear();
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
void LRUCache<T, K>::ClearCounters()
|
||||
{
|
||||
flag = !flag;
|
||||
newsize = foundsize = 0;
|
||||
}
|
||||
|
||||
template <class T, class K>
|
||||
T& LRUCache<T, K>::Get(const Maker& m)
|
||||
{
|
||||
Key k;
|
||||
k.key = m.Key();
|
||||
k.type = typeid(m).name();
|
||||
int q = key.Find(k);
|
||||
if(q < 0) {
|
||||
q = key.Put(k);
|
||||
Item& t = data.At(q);
|
||||
t.size = m.Make(t.data.Create()) + InternalSize;
|
||||
size += t.size;
|
||||
newsize += t.size;
|
||||
t.flag = flag;
|
||||
}
|
||||
else {
|
||||
Item& t = data[q];
|
||||
Unlink(q);
|
||||
if(t.flag != flag) {
|
||||
t.flag = flag;
|
||||
foundsize += t.size;
|
||||
}
|
||||
}
|
||||
LinkHead(q);
|
||||
return *data[q].data;
|
||||
}
|
||||
134
uppsrc/Core/PackedData.cpp
Normal file
134
uppsrc/Core/PackedData.cpp
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
#include "Core.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
PackedData::~PackedData()
|
||||
{
|
||||
if(ptr) MemoryFree(ptr);
|
||||
}
|
||||
|
||||
void PackedData::Clear()
|
||||
{
|
||||
if(ptr) MemoryFree(ptr);
|
||||
ptr = nullptr;
|
||||
}
|
||||
|
||||
Vector<String> PackedData::Unpack() const
|
||||
{
|
||||
Vector<String> r;
|
||||
const byte *s = (const byte *)ptr;
|
||||
for(;;) {
|
||||
int len = *s++;
|
||||
if(len == 255)
|
||||
break;
|
||||
if(len == 254) {
|
||||
memcpy(&len, s, 4);
|
||||
s += 4;
|
||||
}
|
||||
r << String(s, len);
|
||||
s += len;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void PackedData::SetData(int ii, const void *data, int datalen)
|
||||
{
|
||||
size_t alloc = 32;
|
||||
char *result = (char *)MemoryAllocSz(alloc);
|
||||
char *t = result;
|
||||
auto Reserve = [&](int n) {
|
||||
size_t needs = t + n - result;
|
||||
if(needs > alloc) {
|
||||
alloc = 3 * needs / 2;
|
||||
char *r2 = (char *)MemoryAllocSz(alloc);
|
||||
memcpy(r2, result, t - result);
|
||||
MemoryFree(result);
|
||||
t = t - result + r2;
|
||||
result = r2;
|
||||
}
|
||||
};
|
||||
auto Out1 = [&](int c) {
|
||||
Reserve(1);
|
||||
*t++ = c;
|
||||
};
|
||||
auto Out = [&](const void *s, int len) {
|
||||
Reserve(len);
|
||||
memcpy(t, s, len);
|
||||
t += len;
|
||||
};
|
||||
int i = 0;
|
||||
const byte *p = (const byte *)ptr;
|
||||
const byte *s = p;
|
||||
const byte *b = s; // before last control code
|
||||
const byte *rb = NULL; // start of replaced area
|
||||
const byte *re = NULL; // end of replaced area
|
||||
if(s)
|
||||
for(;;) {
|
||||
b = s;
|
||||
int len = *s++;
|
||||
if(len == 255)
|
||||
break;
|
||||
if(len == 254) {
|
||||
memcpy(&len, s, sizeof(int));
|
||||
s += sizeof(int);
|
||||
}
|
||||
if(i == ii) {
|
||||
rb = b;
|
||||
s += len;
|
||||
re = s;
|
||||
}
|
||||
else
|
||||
s += len;
|
||||
i++;
|
||||
}
|
||||
|
||||
auto Put = [&]() {
|
||||
if(datalen < 254)
|
||||
Out1(datalen);
|
||||
else {
|
||||
Out1(254);
|
||||
byte h[sizeof(int)];
|
||||
memcpy(h, &datalen, sizeof(int));
|
||||
Out(h, sizeof(int));
|
||||
}
|
||||
Out(data, datalen);
|
||||
};
|
||||
if(rb) { // we have found an area to replace
|
||||
Out(p, int(rb - p));
|
||||
Put();
|
||||
Out(re, int((s - re)));
|
||||
}
|
||||
else { // we need to add new entries
|
||||
if(p) // copy existing entries
|
||||
Out(p, int(b - p));
|
||||
while(i < ii) {
|
||||
Out1(0);
|
||||
i++;
|
||||
}
|
||||
Put();
|
||||
Out1(255);
|
||||
}
|
||||
if(ptr)
|
||||
MemoryFree(ptr);
|
||||
ptr = result;
|
||||
}
|
||||
|
||||
size_t PackedData::GetPackedSize() const
|
||||
{
|
||||
if(!ptr)
|
||||
return 0;
|
||||
const byte *s = (const byte *)ptr;
|
||||
for(;;) {
|
||||
int len = *s++;
|
||||
if(len == 255)
|
||||
break;
|
||||
if(len == 254) {
|
||||
memcpy(&len, s, 4);
|
||||
s += 4;
|
||||
}
|
||||
s += len;
|
||||
}
|
||||
return s - (const byte *)ptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -2,27 +2,6 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
/* Faster, but consuming more memory....
|
||||
PteBase::Prec *PteBase::PtrAdd()
|
||||
{
|
||||
AtomicInc(prec->n);
|
||||
return prec;
|
||||
}
|
||||
|
||||
void PteBase::PtrRelease(Prec *prec)
|
||||
{
|
||||
if(prec && AtomicDec(prec->n) == 0)
|
||||
delete prec;
|
||||
}
|
||||
|
||||
PteBase::PteBase()
|
||||
{
|
||||
prec = new Prec;
|
||||
prec->n = 1;
|
||||
prec->ptr = this;
|
||||
}
|
||||
*/
|
||||
|
||||
static StaticMutex sPteLock;
|
||||
|
||||
PteBase::Prec *PteBase::PtrAdd()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ protected:
|
|||
|
||||
Prec *PtrAdd();
|
||||
static void PtrRelease(Prec *prec);
|
||||
static Prec *PtrAdd(const Uuid& uuid);
|
||||
|
||||
PteBase();
|
||||
~PteBase();
|
||||
|
|
|
|||
|
|
@ -290,6 +290,8 @@ bool ValueMap::Data::IsNull() const {
|
|||
|
||||
void ValueMap::Data::Serialize(Stream& s) {
|
||||
s % key % value;
|
||||
if(key.GetCount() != value.GetCount())
|
||||
s.LoadError();
|
||||
}
|
||||
|
||||
void ValueMap::Data::Xmlize(XmlIO& xio)
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ void Bits::Serialize(Stream& s)
|
|||
if(s.IsStoring())
|
||||
dwords = GetLast() + 1;
|
||||
s % dwords;
|
||||
if(dwords < 0)
|
||||
s.LoadError();
|
||||
if(s.IsLoading())
|
||||
CreateRaw(dwords);
|
||||
s.SerializeRaw(bp, dwords);
|
||||
|
|
|
|||
|
|
@ -737,11 +737,12 @@ void BiVector<T>::Free() {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef UPP
|
||||
template <class T>
|
||||
void BiVector<T>::Serialize(Stream& s) {
|
||||
int n = items;
|
||||
s / n;
|
||||
if(n < 0)
|
||||
s.LoadError();
|
||||
if(s.IsLoading()) {
|
||||
Clear();
|
||||
while(n--)
|
||||
|
|
@ -758,8 +759,6 @@ String BiVector<T>::ToString() const
|
|||
return AsStringArray(*this);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
BiVector<T>::BiVector(std::initializer_list<T> init)
|
||||
{
|
||||
|
|
@ -794,11 +793,12 @@ void BiArray<T>::DeepCopy0(const BiArray<T>& v) {
|
|||
bv.AddTail() = new T(clone(v[i]));
|
||||
}
|
||||
|
||||
#ifdef UPP
|
||||
template <class T>
|
||||
void BiArray<T>::Serialize(Stream& s) {
|
||||
int n = bv.GetCount();
|
||||
s / n;
|
||||
if(n < 0)
|
||||
s.LoadError();
|
||||
if(s.IsLoading()) {
|
||||
Clear();
|
||||
while(n--)
|
||||
|
|
@ -822,8 +822,6 @@ BiArray<T>::BiArray(std::initializer_list<T> init)
|
|||
AddTail(q);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline
|
||||
void Bits::Set(int i, dword bits, int count)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ template<> void XmlAttrLoad(dword& var, const String& text)
|
|||
|
||||
template<> String XmlAttrStore(const double& var)
|
||||
{
|
||||
return FormatG(var, 17);
|
||||
return FormatG(var, 15);
|
||||
}
|
||||
|
||||
template<> void XmlAttrLoad(double& var, const String& text)
|
||||
|
|
|
|||
|
|
@ -79,7 +79,9 @@ void Ctrl::Layout() {}
|
|||
void Ctrl::PostInput()
|
||||
{
|
||||
GuiLock __;
|
||||
if(parent) parent->PostInput();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->PostInput();
|
||||
}
|
||||
|
||||
void Ctrl::LeftDouble(Point p, dword keyflags)
|
||||
|
|
@ -105,25 +107,33 @@ void Ctrl::RightTriple(Point p, dword keyflags)
|
|||
void Ctrl::ChildGotFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
if(parent) parent->ChildGotFocus();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildGotFocus();
|
||||
}
|
||||
|
||||
void Ctrl::ChildLostFocus()
|
||||
{
|
||||
GuiLock __;
|
||||
if(parent) parent->ChildLostFocus();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildLostFocus();
|
||||
}
|
||||
|
||||
void Ctrl::ChildAdded(Ctrl *q)
|
||||
{
|
||||
GuiLock __;
|
||||
if(parent) parent->ChildAdded(q);
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildAdded(q);
|
||||
}
|
||||
|
||||
void Ctrl::ChildRemoved(Ctrl *q)
|
||||
{
|
||||
GuiLock __;
|
||||
if(parent) parent->ChildRemoved(q);
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildRemoved(q);
|
||||
}
|
||||
|
||||
void Ctrl::ParentChange() {}
|
||||
|
|
@ -287,6 +297,7 @@ void Ctrl::Show(bool ashow) {
|
|||
visible = ashow;
|
||||
fullrefresh = false;
|
||||
RefreshFrame();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
StateH(SHOW);
|
||||
if(top)
|
||||
|
|
@ -301,8 +312,9 @@ bool Ctrl::IsVisible() const {
|
|||
const Ctrl *q = this;
|
||||
for(;;) {
|
||||
if(!q->visible) return false;
|
||||
if(!q->parent) break;
|
||||
q = q->parent;
|
||||
Ctrl *p = q->GetParent();
|
||||
if(!p) break;
|
||||
q = p;
|
||||
}
|
||||
return q->visible;
|
||||
}
|
||||
|
|
@ -312,7 +324,7 @@ void Ctrl::Enable(bool aenable) {
|
|||
if(enabled != aenable) {
|
||||
enabled = aenable;
|
||||
if(top) WndEnable(enabled);
|
||||
if(!enabled && parent && HasFocusDeep())
|
||||
if(!enabled && GetParent() && HasFocusDeep())
|
||||
IterateFocusForward(this, GetTopCtrl());
|
||||
RefreshFrame();
|
||||
StateH(ENABLE);
|
||||
|
|
@ -322,6 +334,7 @@ void Ctrl::Enable(bool aenable) {
|
|||
|
||||
bool Ctrl::IsShowEnabled() const {
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
return IsEnabled() && (!parent || parent->IsShowEnabled());
|
||||
}
|
||||
|
||||
|
|
@ -353,8 +366,8 @@ void Ctrl::ClearModifyDeep()
|
|||
{
|
||||
GuiLock __;
|
||||
ClearModify();
|
||||
for(Ctrl *q = firstchild; q; q = q->next)
|
||||
q->ClearModifyDeep();
|
||||
for(Ctrl& q : *this)
|
||||
q.ClearModifyDeep();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -368,92 +381,14 @@ bool Ctrl::IsModifiedDeep() const
|
|||
{
|
||||
GuiLock __;
|
||||
if(IsModified()) return true;
|
||||
for(Ctrl *q = firstchild; q; q = q->next)
|
||||
if(q->IsModified()) return true;
|
||||
for(const Ctrl& q : *this)
|
||||
if(q.IsModified()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(const Rect& r)
|
||||
{
|
||||
SetCaret(r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
}
|
||||
|
||||
Rect Ctrl::GetCaret() const
|
||||
{
|
||||
return RectC(caretx, carety, caretcx, caretcy);
|
||||
}
|
||||
|
||||
void Ctrl::KillCaret()
|
||||
{
|
||||
SetCaret(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void Ctrl::SetInfoPart(int i, const char *txt)
|
||||
{
|
||||
Vector<String> f = Split(info, '\x7f', false);
|
||||
f.At(i) = txt;
|
||||
info = Join(f, "\x7f");
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::Tip(const char *txt)
|
||||
{
|
||||
SetInfoPart(0, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::HelpLine(const char *txt)
|
||||
{
|
||||
SetInfoPart(1, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::Description(const char *txt)
|
||||
{
|
||||
SetInfoPart(2, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::HelpTopic(const char *txt)
|
||||
{
|
||||
SetInfoPart(3, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::LayoutId(const char *txt)
|
||||
{
|
||||
SetInfoPart(4, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String Ctrl::GetInfoPart(int i) const
|
||||
{
|
||||
Vector<String> f = Split(info, '\x7f', false);
|
||||
return i < f.GetCount() ? f[i] : String();
|
||||
}
|
||||
|
||||
String Ctrl::GetTip() const
|
||||
{
|
||||
return GetInfoPart(0);
|
||||
}
|
||||
|
||||
String Ctrl::GetHelpLine() const
|
||||
{
|
||||
return GetInfoPart(1);
|
||||
}
|
||||
|
||||
String Ctrl::GetDescription() const
|
||||
{
|
||||
return GetInfoPart(2);
|
||||
}
|
||||
|
||||
String Ctrl::GetHelpTopic() const
|
||||
{
|
||||
return GetInfoPart(3);
|
||||
}
|
||||
|
||||
String Ctrl::GetLayoutId() const
|
||||
{
|
||||
return GetInfoPart(4);
|
||||
return Null;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWantFocus() {
|
||||
|
|
@ -493,8 +428,8 @@ void Ctrl::UpdateActionRefresh() {
|
|||
void Ctrl::CancelModeDeep() {
|
||||
GuiLock __;
|
||||
CancelMode();
|
||||
for(Ctrl *q = firstchild; q; q = q->next)
|
||||
q->CancelModeDeep();
|
||||
for(Ctrl& q : *this)
|
||||
q.CancelModeDeep();
|
||||
}
|
||||
|
||||
String Ctrl::GetDesc() const
|
||||
|
|
@ -547,14 +482,14 @@ void Ctrl::Dump(Stream& s) const {
|
|||
sFLAG(wantfocus) << sFLAG(editable) << sFLAG(IsModified()) << sFLAG(transparent));
|
||||
LG("Rect: " << GetRect());
|
||||
LG("View: " << GetView());
|
||||
for(int i = 0; i < frame.GetCount(); i++)
|
||||
LG("Frame " << i << ": " << typeid(decltype(*frame[i].frame)).name() << " - " << frame[i].view);
|
||||
for(int i = 0; i < GetFrameCount(); i++)
|
||||
LG("Frame " << i << ": " << typeid(decltype(*GetFrame0(i).frame)).name() << " - " << GetFrame0(i).GetView());
|
||||
LG("Data: " << GetData().ToString());
|
||||
if(firstchild) {
|
||||
if(children) {
|
||||
LG("Children");
|
||||
s << LOG_BEGIN;
|
||||
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext()) {
|
||||
q->Dump(s);
|
||||
for(const Ctrl& q : *this) {
|
||||
q.Dump(s);
|
||||
LG("------");
|
||||
}
|
||||
s << LOG_END;
|
||||
|
|
@ -592,16 +527,13 @@ Ctrl::Ctrl() {
|
|||
LLOG("Ctrl::Ctrl");
|
||||
GuiPlatformConstruct();
|
||||
destroying = false;
|
||||
parent = prev = next = firstchild = lastchild = NULL;
|
||||
top = NULL;
|
||||
exitcode = 0;
|
||||
frame.Add().frame = &NullFrame();
|
||||
multi_frame = false;
|
||||
frame.frame = &NullFrame();
|
||||
enabled = visible = wantfocus = initfocus = true;
|
||||
editable = true;
|
||||
backpaint = IsCompositedGui() ? FULLBACKPAINT : TRANSPARENTBACKPAINT;
|
||||
inframe = false;
|
||||
ignoremouse = transparent = false;
|
||||
caretcx = caretcy = caretx = carety = 0;
|
||||
pos.x = PosLeft(0, 0);
|
||||
pos.y = PosTop(0, 0);
|
||||
rect = Rect(0, 0, 0, 0);
|
||||
|
|
@ -611,6 +543,9 @@ Ctrl::Ctrl() {
|
|||
popupgrab = false;
|
||||
fullrefresh = false;
|
||||
akv = false;
|
||||
layout_id_literal = false;
|
||||
top = false;
|
||||
uparent = nullptr;
|
||||
}
|
||||
|
||||
void KillTimeCallbacks(void *id, void *idlim);
|
||||
|
|
@ -626,6 +561,7 @@ void Ctrl::DoRemove() {
|
|||
mouseCtrl = NULL;
|
||||
LLOG("DoRemove " << Name() << " focusCtrl: " << UPP::Name(focusCtrl));
|
||||
GuiPlatformRemove();
|
||||
Ctrl *parent = GetParent();
|
||||
if(HasFocusDeep()) {
|
||||
LLOG("DoRemove - HasFocusDeep");
|
||||
if(destroying) {
|
||||
|
|
@ -675,7 +611,7 @@ void Ctrl::Close()
|
|||
Ctrl *q = GetTopCtrl();
|
||||
if(!q->top) return;
|
||||
DoRemove();
|
||||
if(parent) return;
|
||||
if(GetParent()) return;
|
||||
StateH(CLOSE);
|
||||
USRLOG(" CLOSE " + Desc(this));
|
||||
WndDestroy();
|
||||
|
|
@ -689,10 +625,13 @@ Ctrl::~Ctrl() {
|
|||
destroying = true;
|
||||
while(GetFirstChild())
|
||||
RemoveChild(GetFirstChild());
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->RemoveChild(this);
|
||||
Close();
|
||||
KillTimeCallbacks(this, (byte *) this + sizeof(Ctrl));
|
||||
ClearInfo();
|
||||
FreeFrames();
|
||||
}
|
||||
|
||||
Vector<Ctrl::MouseHook>& Ctrl::mousehook() { static Vector<Ctrl::MouseHook> h; return h; }
|
||||
|
|
@ -1035,7 +974,7 @@ String Ctrl::Name0() const {
|
|||
String id = q->GetLayoutId();
|
||||
if(id.GetCount())
|
||||
path = '.' + q->GetLayoutId() + path;
|
||||
q = q->parent;
|
||||
q = q->GetParent();
|
||||
}
|
||||
s << ' ' << path;
|
||||
#ifdef CPU_64
|
||||
|
|
@ -1043,6 +982,7 @@ String Ctrl::Name0() const {
|
|||
#else
|
||||
s << " : " + Format("0x%x", (int) this);
|
||||
#endif
|
||||
Ctrl *parent = GetParent();
|
||||
if(IsChild())
|
||||
s << " (parent " << CppDemangle(typeid(*parent).name()) << ")";
|
||||
return s;
|
||||
|
|
@ -1063,8 +1003,10 @@ void Ctrl::EndLoop()
|
|||
void Ctrl::EndLoop(int code)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(!parent);
|
||||
exitcode = code;
|
||||
ASSERT(!GetParent());
|
||||
TopWindow *w = GetTopWindow();
|
||||
if(w)
|
||||
w->exitcode = code;
|
||||
EndLoop();
|
||||
}
|
||||
|
||||
|
|
@ -1080,12 +1022,6 @@ bool Ctrl::InCurrentLoop() const
|
|||
return GetLoopCtrl() == this;
|
||||
}
|
||||
|
||||
int Ctrl::GetExitCode() const
|
||||
{
|
||||
GuiLock __;
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
#ifdef HAS_TopFrameDraw
|
||||
|
||||
ViewDraw::ViewDraw(Ctrl *ctrl, const Rect& r)
|
||||
|
|
|
|||
181
uppsrc/CtrlCore/CtrlAttr.cpp
Normal file
181
uppsrc/CtrlCore/CtrlAttr.cpp
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
#include "CtrlCore.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
PackedData& Ctrl::Attrs()
|
||||
{
|
||||
if(layout_id_literal) {
|
||||
String layout_id((const char *)attrs.GetRawPtr());
|
||||
attrs.SetRawPtr(nullptr);
|
||||
attrs.SetString(ATTR_LAYOUT_ID, layout_id);
|
||||
layout_id_literal = false;
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void Ctrl::SetTextAttr(int ii, const char *s)
|
||||
{
|
||||
Attrs().SetString(ii, s);
|
||||
}
|
||||
|
||||
void Ctrl::SetTextAttr(int ii, const String& s)
|
||||
{
|
||||
Attrs().SetString(ii, s);
|
||||
}
|
||||
|
||||
String Ctrl::GetTextAttr(int ii) const
|
||||
{
|
||||
return layout_id_literal ? String() : attrs.GetString(ii);
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::Tip(const char *txt)
|
||||
{
|
||||
SetTextAttr(ATTR_TIP, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::HelpLine(const char *txt)
|
||||
{
|
||||
SetTextAttr(ATTR_HELPLINE, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::Description(const char *txt)
|
||||
{
|
||||
SetTextAttr(ATTR_DESCRIPTION, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::HelpTopic(const char *txt)
|
||||
{
|
||||
SetTextAttr(ATTR_HELPTOPIC, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::LayoutId(const char *txt)
|
||||
{
|
||||
SetTextAttr(ATTR_LAYOUT_ID, txt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::LayoutIdLiteral(const char *txt)
|
||||
{
|
||||
if(attrs.GetRawPtr() && !layout_id_literal)
|
||||
LayoutId(txt);
|
||||
else {
|
||||
attrs.SetRawPtr((void *)txt);
|
||||
layout_id_literal = true;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String Ctrl::GetLayoutId() const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return (const char *)attrs.GetRawPtr();
|
||||
return GetTextAttr(ATTR_LAYOUT_ID);
|
||||
}
|
||||
|
||||
String Ctrl::GetTip() const
|
||||
{
|
||||
return GetTextAttr(ATTR_TIP);
|
||||
}
|
||||
|
||||
String Ctrl::GetHelpLine() const
|
||||
{
|
||||
return GetTextAttr(ATTR_HELPLINE);
|
||||
}
|
||||
|
||||
String Ctrl::GetDescription() const
|
||||
{
|
||||
return GetTextAttr(ATTR_DESCRIPTION);
|
||||
}
|
||||
|
||||
String Ctrl::GetHelpTopic() const
|
||||
{
|
||||
return GetTextAttr(ATTR_HELPTOPIC);
|
||||
}
|
||||
|
||||
void Ctrl::ClearInfo()
|
||||
{
|
||||
if(layout_id_literal)
|
||||
attrs.SetRawPtr(nullptr);
|
||||
layout_id_literal = false;
|
||||
attrs.Clear();
|
||||
}
|
||||
|
||||
void Ctrl::SetColorAttr(int ii, Color c)
|
||||
{
|
||||
Attrs();
|
||||
if(IsNull(c))
|
||||
attrs.SetNull(ii);
|
||||
else
|
||||
attrs.SetDword(ii, c.GetRaw());
|
||||
}
|
||||
|
||||
Color Ctrl::GetColorAttr(int ii) const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return Null;
|
||||
static dword nullval = Color(Null).GetRaw();
|
||||
return Color::FromRaw(attrs.GetDword(ii, nullval));
|
||||
}
|
||||
|
||||
void Ctrl::SetFontAttr(int ii, Font fnt)
|
||||
{
|
||||
Attrs();
|
||||
if(IsNull(fnt))
|
||||
attrs.SetNull(ii);
|
||||
else
|
||||
attrs.SetInt64(ii, fnt.AsInt64());
|
||||
}
|
||||
|
||||
Font Ctrl::GetFontAttr(int ii) const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return Null;
|
||||
static dword nullval = Font(Null).AsInt64();
|
||||
return Font::FromInt64(attrs.GetInt64(ii, nullval));
|
||||
}
|
||||
|
||||
void Ctrl::SetIntAttr(int ii, int val)
|
||||
{
|
||||
Attrs().SetInt(ii, val);
|
||||
}
|
||||
|
||||
int Ctrl::GetIntAttr(int ii, int def) const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return def;
|
||||
return attrs.GetInt(ii, def);
|
||||
}
|
||||
|
||||
void Ctrl::SetInt64Attr(int ii, int64 val)
|
||||
{
|
||||
Attrs().SetInt64(ii, val);
|
||||
}
|
||||
|
||||
int Ctrl::GetInt64Attr(int ii, int64 def) const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return def;
|
||||
return attrs.GetInt64(ii, def);
|
||||
}
|
||||
|
||||
|
||||
void Ctrl::SetVoidPtrAttr(int ii, const void *ptr)
|
||||
{
|
||||
if(ptr)
|
||||
Attrs().SetPtr(ii, (void *)ptr);
|
||||
else
|
||||
Attrs().SetNull(ii);
|
||||
}
|
||||
|
||||
void *Ctrl::GetVoidPtrAttr(int ii) const
|
||||
{
|
||||
if(layout_id_literal)
|
||||
return NULL;
|
||||
return attrs.GetPtr(ii);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -4,6 +4,25 @@ namespace Upp {
|
|||
|
||||
#define LLOG(x) // DLOG(x)
|
||||
|
||||
void Ctrl::DeleteTop()
|
||||
{
|
||||
if(top && utop) {
|
||||
delete utop;
|
||||
utop = nullptr;
|
||||
top = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SetParent(Ctrl *parent)
|
||||
{
|
||||
if(top && utop) {
|
||||
Close();
|
||||
DeleteTop(); // if Close did not work as expected...:
|
||||
}
|
||||
uparent = parent;
|
||||
top = false;
|
||||
}
|
||||
|
||||
bool Ctrl::IsDHCtrl() const {
|
||||
return dynamic_cast<const DHCtrl *>(this);
|
||||
}
|
||||
|
|
@ -15,38 +34,31 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p)
|
|||
LLOG("Add " << UPP::Name(q) << " to: " << Name());
|
||||
if(p == q) return;
|
||||
bool updaterect = true;
|
||||
if(q->parent) {
|
||||
Ctrl *qparent = q->GetParent();
|
||||
if(qparent) {
|
||||
ASSERT(!q->inframe);
|
||||
if(q->parent == this) {
|
||||
if(qparent == this) {
|
||||
RemoveChild0(q);
|
||||
updaterect = false;
|
||||
}
|
||||
else
|
||||
q->parent->RemoveChild(q);
|
||||
qparent->RemoveChild(q);
|
||||
}
|
||||
q->parent = this;
|
||||
if(p) {
|
||||
ASSERT(p->parent == this);
|
||||
q->prev = p;
|
||||
q->next = p->next;
|
||||
if(p == lastchild)
|
||||
lastchild = q;
|
||||
else
|
||||
p->next->prev = q;
|
||||
p->next = q;
|
||||
|
||||
if(children) {
|
||||
if(!p) p = GetLastChild();
|
||||
ASSERT(p->GetParent() == this);
|
||||
q->prev_sibling = p;
|
||||
q->next_sibling = p->next_sibling;
|
||||
p->next_sibling->prev_sibling = q;
|
||||
p->next_sibling = q;
|
||||
}
|
||||
else
|
||||
if(firstchild) {
|
||||
q->prev = NULL;
|
||||
q->next = firstchild;
|
||||
firstchild->prev = q;
|
||||
firstchild = q;
|
||||
}
|
||||
else {
|
||||
ASSERT(lastchild == NULL);
|
||||
firstchild = lastchild = q;
|
||||
q->prev = q->next = NULL;
|
||||
}
|
||||
else {
|
||||
ASSERT(!p);
|
||||
children = q->next_sibling = q->prev_sibling = q;
|
||||
}
|
||||
q->SetParent(this);
|
||||
|
||||
q->CancelModeDeep();
|
||||
if(updaterect)
|
||||
q->UpdateRect();
|
||||
|
|
@ -58,13 +70,13 @@ void Ctrl::AddChild(Ctrl *q, Ctrl *p)
|
|||
|
||||
void Ctrl::AddChild(Ctrl *child)
|
||||
{
|
||||
AddChild(child, lastchild);
|
||||
AddChild(child, GetLastChild());
|
||||
}
|
||||
|
||||
void Ctrl::AddChildBefore(Ctrl *child, Ctrl *insbefore)
|
||||
{
|
||||
if(insbefore)
|
||||
AddChild(child, insbefore->prev);
|
||||
AddChild(child, insbefore->GetPrev());
|
||||
else
|
||||
AddChild(child);
|
||||
}
|
||||
|
|
@ -73,23 +85,26 @@ void Ctrl::RemoveChild0(Ctrl *q)
|
|||
{
|
||||
GuiLock __;
|
||||
ChildRemoved(q);
|
||||
if(!q->GetParent()) return; // ChildRemoved can remove q
|
||||
q->DoRemove();
|
||||
q->parent = NULL;
|
||||
if(q == firstchild)
|
||||
firstchild = firstchild->next;
|
||||
if(q == lastchild)
|
||||
lastchild = lastchild->prev;
|
||||
if(q->prev)
|
||||
q->prev->next = q->next;
|
||||
if(q->next)
|
||||
q->next->prev = q->prev;
|
||||
q->next = q->prev = NULL;
|
||||
if(!q->GetParent()) return; // DoRemove can remove q
|
||||
q->SetParent(NULL);
|
||||
|
||||
if(q == children) {
|
||||
children = q->next_sibling;
|
||||
if(children == q)
|
||||
children = NULL;
|
||||
}
|
||||
|
||||
q->prev_sibling->next_sibling = q->next_sibling;
|
||||
q->next_sibling->prev_sibling = q->prev_sibling;
|
||||
q->next_sibling = q->prev_sibling = NULL;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveChild(Ctrl *q)
|
||||
{
|
||||
GuiLock __;
|
||||
if(q->parent != this) return;
|
||||
if(q->GetParent() != this) return;
|
||||
q->RefreshFrame();
|
||||
RemoveChild0(q);
|
||||
q->ParentChange();
|
||||
|
|
@ -100,6 +115,7 @@ void Ctrl::RemoveChild(Ctrl *q)
|
|||
void Ctrl::Remove()
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->RemoveChild(this);
|
||||
}
|
||||
|
|
@ -171,15 +187,16 @@ Ctrl * Ctrl::GetViewIndexChild(int ii) const
|
|||
bool Ctrl::HasChild(Ctrl *q) const
|
||||
{
|
||||
GuiLock __;
|
||||
return q && q->IsChild() && q->parent == this;
|
||||
return q && q->GetParent() == this;
|
||||
}
|
||||
|
||||
bool Ctrl::HasChildDeep(Ctrl *q) const
|
||||
{
|
||||
GuiLock __;
|
||||
while(q && q->IsChild()) {
|
||||
if(q->parent == this) return true;
|
||||
q = q->parent;
|
||||
Ctrl *qparent = q->GetParent();
|
||||
if(qparent == this) return true;
|
||||
q = qparent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -260,9 +277,12 @@ Ctrl *Ctrl::GetTopCtrl()
|
|||
{
|
||||
GuiLock __;
|
||||
Ctrl *q = this;
|
||||
while(q->parent)
|
||||
q = q->parent;
|
||||
return q;
|
||||
for(;;) {
|
||||
Ctrl *qparent = q->GetParent();
|
||||
if(!qparent)
|
||||
return q;
|
||||
q = qparent;
|
||||
}
|
||||
}
|
||||
|
||||
const Ctrl *Ctrl::GetTopCtrl() const { return const_cast<Ctrl *>(this)->GetTopCtrl(); }
|
||||
|
|
@ -270,7 +290,7 @@ const Ctrl *Ctrl::GetOwner() const { return const_cast<Ctrl *>(this)->Get
|
|||
Ctrl *Ctrl::GetTopCtrlOwner() { return GetTopCtrl()->GetOwner(); }
|
||||
const Ctrl *Ctrl::GetTopCtrlOwner() const { return GetTopCtrl()->GetOwner(); }
|
||||
|
||||
Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top ? top->owner : NULL; }
|
||||
Ctrl *Ctrl::GetOwnerCtrl() { GuiLock __; return !IsChild() && top && utop ? utop->owner : NULL; }
|
||||
const Ctrl *Ctrl::GetOwnerCtrl() const { return const_cast<Ctrl *>(this)->GetOwnerCtrl(); }
|
||||
|
||||
TopWindow *Ctrl::GetTopWindow()
|
||||
|
|
|
|||
|
|
@ -478,14 +478,29 @@ private:
|
|||
void operator=(Ctrl&);
|
||||
|
||||
private:
|
||||
struct Frame : Moveable<Frame> {
|
||||
CtrlFrame *frame;
|
||||
Rect16 view;
|
||||
|
||||
Frame() { view.Clear(); }
|
||||
struct MultiFrame { // in case there are more than 1 CtrlFrames
|
||||
int alloc;
|
||||
int count;
|
||||
};
|
||||
Ctrl *parent;
|
||||
|
||||
struct Rect16_ { // so that it can be in union
|
||||
int16 left, top, right, bottom;
|
||||
};
|
||||
|
||||
struct Frame {
|
||||
union {
|
||||
CtrlFrame *frame;
|
||||
Frame *frames;
|
||||
};
|
||||
union {
|
||||
MultiFrame multi;
|
||||
Rect16_ view;
|
||||
};
|
||||
|
||||
void SetView(const Rect& r) { view.left = r.left; view.right = r.right; view.top = r.top; view.bottom = r.bottom; }
|
||||
Rect GetView() const { return Rect16(view.left, view.top, view.right, view.bottom); }
|
||||
};
|
||||
|
||||
struct Scroll : Moveable<Scroll> {
|
||||
Rect rect;
|
||||
int dx;
|
||||
|
|
@ -508,16 +523,20 @@ private:
|
|||
Ptr<Ctrl> owner;
|
||||
};
|
||||
|
||||
Top *top;
|
||||
int exitcode;
|
||||
|
||||
Ctrl *prev, *next;
|
||||
Ctrl *firstchild, *lastchild;//16
|
||||
Frame frame;
|
||||
LogPos pos;//8
|
||||
Rect16 rect;
|
||||
Mitor<Frame> frame;//16
|
||||
String info;//16
|
||||
int16 caretx, carety, caretcx, caretcy;//8
|
||||
Rect16 rect; //8
|
||||
|
||||
union {
|
||||
Ctrl *uparent;
|
||||
Top *utop;
|
||||
};
|
||||
|
||||
Ctrl *prev_sibling = nullptr;
|
||||
Ctrl *next_sibling = nullptr;
|
||||
Ctrl *children = nullptr;
|
||||
PackedData attrs;
|
||||
|
||||
byte overpaint;
|
||||
|
||||
|
|
@ -543,6 +562,9 @@ private:
|
|||
|
||||
bool akv:1;
|
||||
bool destroying:1;
|
||||
bool layout_id_literal:1; // info_ptr points to layout char * literal, no heap involved
|
||||
bool multi_frame:1; // there is more than single frame, they are stored in heap
|
||||
bool top:1;
|
||||
|
||||
static Ptr<Ctrl> eventCtrl;
|
||||
static Ptr<Ctrl> mouseCtrl;
|
||||
|
|
@ -551,8 +573,6 @@ private:
|
|||
static Ptr<Ctrl> focusCtrl;
|
||||
static Ptr<Ctrl> focusCtrlWnd;
|
||||
static Ptr<Ctrl> lastActiveWnd;
|
||||
static Ptr<Ctrl> caretCtrl;
|
||||
static Rect caretRect;
|
||||
static Ptr<Ctrl> captureCtrl;
|
||||
static bool ignoreclick;
|
||||
static bool ignoremouseup;
|
||||
|
|
@ -634,12 +654,20 @@ private:
|
|||
void RefreshAccessKeys();
|
||||
void RefreshAccessKeysDo(bool vis);
|
||||
static void DefferedFocusSync();
|
||||
static void SyncCaret();
|
||||
static void RefreshCaret();
|
||||
static bool DispatchKey(dword keycode, int count);
|
||||
void SetFocusWnd();
|
||||
void KillFocusWnd();
|
||||
|
||||
static Ptr<Ctrl> caretCtrl;
|
||||
static Ptr<Ctrl> prevCaretCtrl;
|
||||
static Rect caretRect;
|
||||
static int WndCaretTime;
|
||||
static bool WndCaretVisible;
|
||||
|
||||
static void AnimateCaret();
|
||||
static void SyncCaret();
|
||||
static void RefreshCaret();
|
||||
|
||||
static Ptr<Ctrl> dndctrl;
|
||||
static Point dndpos;
|
||||
static bool dndframe;
|
||||
|
|
@ -667,8 +695,6 @@ private:
|
|||
void UpdateArea(SystemDraw& draw, const Rect& clip);
|
||||
Ctrl *GetTopRect(Rect& r, bool inframe, bool clip = true);
|
||||
void DoSync(Ctrl *q, Rect r, bool inframe);
|
||||
void SetInfoPart(int i, const char *txt);
|
||||
String GetInfoPart(int i) const;
|
||||
|
||||
Rect GetPreeditScreenRect();
|
||||
void SyncPreedit();
|
||||
|
|
@ -718,6 +744,21 @@ private:
|
|||
void SysEndLoop();
|
||||
|
||||
String Name0() const;
|
||||
|
||||
Top *GetTop() { return top ? utop : NULL; }
|
||||
const Top *GetTop() const { return top ? utop : NULL; }
|
||||
void DeleteTop();
|
||||
|
||||
void SetTop(Top *t) { utop = t; top = true; }
|
||||
void SetParent(Ctrl *parent);
|
||||
|
||||
Frame& GetFrame0(int i) { ASSERT(i < GetFrameCount()); return multi_frame ? frame.frames[i] : frame; }
|
||||
const Frame& GetFrame0(int i) const { ASSERT(i < GetFrameCount()); return multi_frame ? frame.frames[i] : frame; }
|
||||
void FreeFrames() { if(multi_frame) MemoryFree(frame.frames); }
|
||||
Frame AllocFrames(int alloc);
|
||||
|
||||
PackedData& Attrs();
|
||||
|
||||
|
||||
static void InitTimer();
|
||||
|
||||
|
|
@ -779,7 +820,44 @@ protected:
|
|||
static void TimerProc(dword time);
|
||||
|
||||
Ctrl& Unicode() { unicode = true; return *this; }
|
||||
|
||||
enum {
|
||||
ATTR_LAYOUT_ID,
|
||||
ATTR_TIP,
|
||||
ATTR_HELPLINE,
|
||||
ATTR_DESCRIPTION,
|
||||
ATTR_HELPTOPIC,
|
||||
ATTR_LAST
|
||||
};
|
||||
|
||||
void SetTextAttr(int ii, const char *s);
|
||||
void SetTextAttr(int ii, const String& s);
|
||||
String GetTextAttr(int ii) const;
|
||||
|
||||
void SetColorAttr(int ii, Color c);
|
||||
Color GetColorAttr(int ii) const;
|
||||
|
||||
void SetFontAttr(int ii, Font fnt);
|
||||
Font GetFontAttr(int ii) const;
|
||||
|
||||
void SetIntAttr(int ii, int val);
|
||||
int GetIntAttr(int ii, int def = Null) const;
|
||||
|
||||
void SetInt64Attr(int ii, int64 val);
|
||||
int GetInt64Attr(int ii, int64 def = Null) const;
|
||||
|
||||
void SetVoidPtrAttr(int ii, const void *ptr);
|
||||
void *GetVoidPtrAttr(int ii) const;
|
||||
|
||||
template <class T>
|
||||
T& CreateAttr(int ii) { T *q = new T; SetVoidPtrAttr(ii, q); return *q; }
|
||||
|
||||
template <class T>
|
||||
T GetAttr(int ii) const { void *p = GetVoidPtrAttr(ii); return p ? *(T *)p : T(); }
|
||||
|
||||
template <class T>
|
||||
void DeleteAttr(int ii) { void *p = GetVoidPtrAttr(ii); if(p) { delete (T *)p; SetVoidPtrAttr(ii, nullptr); }; }
|
||||
|
||||
public:
|
||||
enum StateReason {
|
||||
FOCUS = 10,
|
||||
|
|
@ -915,6 +993,8 @@ public:
|
|||
virtual Point GetPreedit();
|
||||
virtual Font GetPreeditFont();
|
||||
|
||||
virtual Rect GetCaret() const;
|
||||
|
||||
virtual void DragAndDrop(Point p, PasteClip& d);
|
||||
virtual void FrameDragAndDrop(Point p, PasteClip& d);
|
||||
virtual void DragRepeat(Point p);
|
||||
|
|
@ -972,11 +1052,11 @@ public:
|
|||
void AddChild(Ctrl *child, Ctrl *insafter);
|
||||
void AddChildBefore(Ctrl *child, Ctrl *insbefore);
|
||||
void RemoveChild(Ctrl *child);
|
||||
Ctrl *GetParent() const { return parent; }
|
||||
Ctrl *GetLastChild() const { return lastchild; }
|
||||
Ctrl *GetFirstChild() const { return firstchild; }
|
||||
Ctrl *GetPrev() const { return parent ? prev : NULL; }
|
||||
Ctrl *GetNext() const { return parent ? next : NULL; }
|
||||
Ctrl *GetParent() const { return top ? NULL : uparent; }
|
||||
Ctrl *GetLastChild() const { return children ? children->prev_sibling : nullptr; }
|
||||
Ctrl *GetFirstChild() const { return children; }
|
||||
Ctrl *GetPrev() const { Ctrl *parent = GetParent(); return parent && prev_sibling != parent->GetLastChild() ? prev_sibling : nullptr; }
|
||||
Ctrl *GetNext() const { Ctrl *parent = GetParent(); return parent && next_sibling != parent->children ? next_sibling : nullptr; }
|
||||
int GetChildIndex(const Ctrl *child) const;
|
||||
Ctrl *GetIndexChild(int i) const;
|
||||
int GetChildCount() const;
|
||||
|
|
@ -987,7 +1067,7 @@ public:
|
|||
int GetViewChildCount() const;
|
||||
Ctrl *GetViewIndexChild(int ii) const;
|
||||
|
||||
bool IsChild() const { return parent; }
|
||||
bool IsChild() const { return GetParent(); }
|
||||
|
||||
Ctrl *ChildFromPoint(Point& pt) const;
|
||||
|
||||
|
|
@ -1013,13 +1093,13 @@ public:
|
|||
Ctrl& SetFrame(int i, CtrlFrame& frm);
|
||||
Ctrl& SetFrame(CtrlFrame& frm) { return SetFrame(0, frm); }
|
||||
Ctrl& AddFrame(CtrlFrame& frm);
|
||||
const CtrlFrame& GetFrame(int i = 0) const { return *frame[i].frame; }
|
||||
CtrlFrame& GetFrame(int i = 0) { return *frame[i].frame; }
|
||||
const CtrlFrame& GetFrame(int i = 0) const { return *const_cast<Ctrl *>(this)->GetFrame0(i).frame; }
|
||||
CtrlFrame& GetFrame(int i = 0) { return *GetFrame0(i).frame; }
|
||||
void RemoveFrame(int i);
|
||||
void RemoveFrame(CtrlFrame& frm);
|
||||
void InsertFrame(int i, CtrlFrame& frm);
|
||||
int FindFrame(CtrlFrame& frm);
|
||||
int GetFrameCount() const { return frame.GetCount(); }
|
||||
int FindFrame(CtrlFrame& frm) const;
|
||||
int GetFrameCount() const { return multi_frame ? frame.multi.count : frame.frame ? 1 : 0; }
|
||||
void ClearFrames();
|
||||
|
||||
bool IsOpen() const;
|
||||
|
|
@ -1055,10 +1135,10 @@ public:
|
|||
|
||||
void RefreshLayout() { SyncLayout(1); }
|
||||
void RefreshLayoutDeep() { SyncLayout(2); }
|
||||
void RefreshParentLayout() { if(parent) parent->RefreshLayout(); }
|
||||
void RefreshParentLayout();
|
||||
|
||||
void UpdateLayout() { SyncLayout(); }
|
||||
void UpdateParentLayout() { if(parent) parent->UpdateLayout(); }
|
||||
void UpdateParentLayout();
|
||||
|
||||
Ctrl& LeftPos(int a, int size = STDSIZE);
|
||||
Ctrl& RightPos(int a, int size = STDSIZE);
|
||||
|
|
@ -1157,11 +1237,6 @@ public:
|
|||
|
||||
void CancelModeDeep();
|
||||
|
||||
void SetCaret(int x, int y, int cx, int cy);
|
||||
void SetCaret(const Rect& r);
|
||||
Rect GetCaret() const;
|
||||
void KillCaret();
|
||||
|
||||
static void CancelPreedit();
|
||||
|
||||
void CancelMyPreedit() { if(HasFocus()) CancelPreedit(); }
|
||||
|
|
@ -1211,21 +1286,19 @@ public:
|
|||
Ctrl& NoTransparent() { return Transparent(false); }
|
||||
bool IsTransparent() const { return transparent; }
|
||||
|
||||
Ctrl& Info(const char *txt) { info = txt; return *this; }
|
||||
String GetInfo() const { return info; }
|
||||
|
||||
Ctrl& Tip(const char *txt);
|
||||
Ctrl& HelpLine(const char *txt);
|
||||
Ctrl& Description(const char *txt);
|
||||
Ctrl& HelpTopic(const char *txt);
|
||||
Ctrl& LayoutId(const char *txt);
|
||||
Ctrl& LayoutIdLiteral(const char *txt);
|
||||
|
||||
String GetTip() const;
|
||||
String GetHelpLine() const;
|
||||
String GetDescription() const;
|
||||
String GetHelpTopic() const;
|
||||
String GetLayoutId() const;
|
||||
void ClearInfo() { info.Clear(); }
|
||||
void ClearInfo();
|
||||
|
||||
void Add(Ctrl& ctrl) { AddChild(&ctrl); }
|
||||
Ctrl& operator<<(Ctrl& ctrl) { Add(ctrl); return *this; }
|
||||
|
|
@ -1276,7 +1349,6 @@ public:
|
|||
void EndLoop(int code);
|
||||
bool InLoop() const;
|
||||
bool InCurrentLoop() const;
|
||||
int GetExitCode() const;
|
||||
|
||||
static PasteClip& Clipboard();
|
||||
static PasteClip& Selection();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,9 @@ file
|
|||
Frame.cpp,
|
||||
CtrlMt.cpp,
|
||||
Ctrl.cpp,
|
||||
CtrlAttr.cpp,
|
||||
CtrlChild.cpp,
|
||||
CtrlFrame.cpp,
|
||||
CtrlPos.cpp,
|
||||
CtrlDraw.cpp,
|
||||
CtrlMouse.cpp,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ void Ctrl::RefreshFrame(const Rect& r) {
|
|||
if(GuiPlatformRefreshFrameSpecial(r))
|
||||
return;
|
||||
if(!top && !IsDHCtrl()) {
|
||||
Ctrl *parent = GetParent();
|
||||
if(InFrame())
|
||||
parent->RefreshFrame(r + GetRect().TopLeft());
|
||||
else
|
||||
|
|
@ -83,6 +84,7 @@ void Ctrl::ScrollRefresh(const Rect& r, int dx, int dy)
|
|||
bool Ctrl::AddScroll(const Rect& sr, int dx, int dy)
|
||||
{
|
||||
GuiLock __;
|
||||
Top *top = GetTop();
|
||||
if(!top)
|
||||
return true;
|
||||
for(int i = 0; i < top->scroll.GetCount(); i++) {
|
||||
|
|
@ -113,12 +115,12 @@ Rect Ctrl::GetClippedView()
|
|||
GuiLock __;
|
||||
Rect sv = GetScreenView();
|
||||
Rect view = sv;
|
||||
Ctrl *q = parent;
|
||||
Ctrl *q = GetParent();
|
||||
Ctrl *w = this;
|
||||
while(q) {
|
||||
view &= w->InFrame() ? q->GetScreenRect() : q->GetScreenView();
|
||||
w = q;
|
||||
q = q->parent;
|
||||
q = q->GetParent();
|
||||
}
|
||||
return view - GetScreenRect().TopLeft();
|
||||
}
|
||||
|
|
@ -178,7 +180,7 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy)
|
|||
Rect r = _r & vsz;
|
||||
LLOG("ScrollView2 " << r << " " << dx << " " << dy);
|
||||
Ctrl *w;
|
||||
for(w = this; w->parent; w = w->parent)
|
||||
for(w = this; w->GetParent(); w = w->GetParent())
|
||||
if(w->InFrame()) {
|
||||
Refresh();
|
||||
return;
|
||||
|
|
@ -191,12 +193,12 @@ void Ctrl::ScrollView(const Rect& _r, int dx, int dy)
|
|||
Refresh();
|
||||
else {
|
||||
LTIMING("ScrollCtrls1");
|
||||
Top *top = GetTopCtrl()->top;
|
||||
Top *top = GetTopCtrl()->GetTop();
|
||||
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
|
||||
if(q->InView())
|
||||
ScrollCtrl(top, q, r, q->GetRect(), dx, dy);
|
||||
if(parent)
|
||||
for(Ctrl *q = parent->GetFirstChild(); q; q = q->GetNext())
|
||||
if(GetParent())
|
||||
for(Ctrl *q = GetParent()->GetFirstChild(); q; q = q->GetNext())
|
||||
if(q->InView() && q != this)
|
||||
ScrollCtrl(top, q, r, q->GetScreenRect() - GetScreenView().TopLeft(), dx, dy);
|
||||
}
|
||||
|
|
@ -214,6 +216,7 @@ void Ctrl::ScrollView(int dx, int dy) {
|
|||
void Ctrl::SyncScroll()
|
||||
{
|
||||
GuiLock __;
|
||||
Top *top = GetTop();
|
||||
if(!top)
|
||||
return;
|
||||
Vector<Scroll> scroll = pick(top->scroll);
|
||||
|
|
@ -278,29 +281,31 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
|
|||
return;
|
||||
Ctrl *q;
|
||||
Rect view = rect;
|
||||
for(int i = 0; i < frame.GetCount(); i++) {
|
||||
int n = GetFrameCount();
|
||||
for(int i = 0; i < n; i++) {
|
||||
LEVELCHECK(w, NULL);
|
||||
frame[i].frame->FramePaint(w, view);
|
||||
view = frame[i].view;
|
||||
Frame& f = GetFrame0(i);
|
||||
f.frame->FramePaint(w, view);
|
||||
view = f.GetView();
|
||||
}
|
||||
Rect oview = view.Inflated(overpaint);
|
||||
bool hasviewctrls = false;
|
||||
bool viewexcluded = false;
|
||||
bool hiddenbychild = false;
|
||||
for(q = firstchild; q; q = q->next)
|
||||
if(q->IsShown()) {
|
||||
if(q->GetRect().Contains(orect) && !q->IsTransparent())
|
||||
for(Ctrl& q : *this)
|
||||
if(q.IsShown()) {
|
||||
if(q.GetRect().Contains(orect) && !q.IsTransparent())
|
||||
hiddenbychild = true;
|
||||
if(q->InFrame()) {
|
||||
if(!viewexcluded && IsTransparent() && q->GetRect().Intersects(view)) {
|
||||
if(q.InFrame()) {
|
||||
if(!viewexcluded && IsTransparent() && q.GetRect().Intersects(view)) {
|
||||
w.Begin();
|
||||
w.ExcludeClip(view);
|
||||
viewexcluded = true;
|
||||
}
|
||||
LEVELCHECK(w, q);
|
||||
Point off = q->GetRect().TopLeft();
|
||||
LEVELCHECK(w, &q);
|
||||
Point off = q.GetRect().TopLeft();
|
||||
w.Offset(off);
|
||||
q->CtrlPaint(w, clip - off);
|
||||
q.CtrlPaint(w, clip - off);
|
||||
w.End();
|
||||
}
|
||||
else
|
||||
|
|
@ -329,15 +334,15 @@ void Ctrl::CtrlPaint(SystemDraw& w, const Rect& clip) {
|
|||
if(hasviewctrls && !view.IsEmpty()) {
|
||||
Rect cl = clip & view;
|
||||
w.Clip(cl);
|
||||
for(q = firstchild; q; q = q->next)
|
||||
if(q->IsShown() && q->InView()) {
|
||||
LEVELCHECK(w, q);
|
||||
Rect qr = q->GetRect();
|
||||
for(Ctrl& q : *this)
|
||||
if(q.IsShown() && q.InView()) {
|
||||
LEVELCHECK(w, &q);
|
||||
Rect qr = q.GetRect();
|
||||
Point off = qr.TopLeft() + view.TopLeft();
|
||||
Rect ocl = cl - off;
|
||||
if(ocl.Intersects(Rect(qr.GetSize()).Inflated(overpaint))) {
|
||||
w.Offset(off);
|
||||
q->CtrlPaint(w, ocl);
|
||||
q.CtrlPaint(w, ocl);
|
||||
w.End();
|
||||
}
|
||||
}
|
||||
|
|
@ -373,11 +378,11 @@ bool Ctrl::PaintOpaqueAreas(SystemDraw& w, const Rect& r, const Rect& clip, bool
|
|||
if(backpaint == EXCLUDEPAINT)
|
||||
return w.ExcludeClip(r);
|
||||
Rect cview = clip & (GetView() + off);
|
||||
for(Ctrl *q = lastchild; q; q = q->prev)
|
||||
if(!q->PaintOpaqueAreas(w, q->GetRect() + (q->InView() ? viewpos : off),
|
||||
q->InView() ? cview : clip))
|
||||
for(Ctrl& q : *this)
|
||||
if(!q.PaintOpaqueAreas(w, q.GetRect() + (q.InView() ? viewpos : off),
|
||||
q.InView() ? cview : clip))
|
||||
return false;
|
||||
if(nochild && (lastchild || GetNext()))
|
||||
if(nochild && (GetLastChild() || GetNext()))
|
||||
return true;
|
||||
Rect opaque = (GetOpaqueRect() + viewpos) & clip;
|
||||
if(opaque.IsEmpty())
|
||||
|
|
@ -461,11 +466,11 @@ void Ctrl::GatherTransparentAreas(Vector<Rect>& area, SystemDraw& w, Rect r, con
|
|||
CombineArea(area, clip & Rect(notr.left, r.top, notr.right, notr.top));
|
||||
CombineArea(area, clip & Rect(notr.left, notr.bottom, notr.right, r.bottom));
|
||||
}
|
||||
for(Ctrl *q = firstchild; q; q = q->next) {
|
||||
Point qoff = q->InView() ? viewpos : off;
|
||||
Rect qr = q->GetRect() + qoff;
|
||||
for(Ctrl& q : *this) {
|
||||
Point qoff = q.InView() ? viewpos : off;
|
||||
Rect qr = q.GetRect() + qoff;
|
||||
if(clip.Intersects(qr))
|
||||
q->GatherTransparentAreas(area, w, qr, clip);
|
||||
q.GatherTransparentAreas(area, w, qr, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -506,9 +511,9 @@ void Ctrl::ExcludeDHCtrls(SystemDraw& w, const Rect& r, const Rect& clip)
|
|||
return;
|
||||
}
|
||||
Rect cview = clip & (GetView() + off);
|
||||
for(Ctrl *q = lastchild; q; q = q->prev)
|
||||
q->ExcludeDHCtrls(w, q->GetRect() + (q->InView() ? viewpos : off),
|
||||
q->InView() ? cview : clip);
|
||||
for(Ctrl& q : *this)
|
||||
q.ExcludeDHCtrls(w, q.GetRect() + (q.InView() ? viewpos : off),
|
||||
q.InView() ? cview : clip);
|
||||
}
|
||||
|
||||
void Ctrl::UpdateArea0(SystemDraw& draw, const Rect& clip, int backpaint)
|
||||
|
|
@ -597,6 +602,7 @@ Ctrl *Ctrl::GetTopRect(Rect& r, bool inframe, bool clip)
|
|||
r &= Rect(GetSize());
|
||||
r.Offset(GetView().TopLeft());
|
||||
}
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent) {
|
||||
r.Offset(GetRect().TopLeft());
|
||||
return parent->GetTopRect(r, InFrame(), clip);
|
||||
|
|
@ -620,6 +626,7 @@ void Ctrl::Sync()
|
|||
{
|
||||
GuiLock __;
|
||||
LLOG("Sync " << Name());
|
||||
Ctrl *parent = GetParent();
|
||||
if(top && IsOpen()) {
|
||||
LLOG("Sync UpdateWindow " << Name());
|
||||
SyncScroll();
|
||||
|
|
@ -642,6 +649,7 @@ void Ctrl::Sync(const Rect& sr)
|
|||
void Ctrl::DrawCtrlWithParent(Draw& w, int x, int y)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent) {
|
||||
Rect r = GetRect();
|
||||
Ctrl *top = parent->GetTopRect(r, inframe);
|
||||
|
|
@ -674,6 +682,7 @@ void Ctrl::DrawCtrl(Draw& w, int x, int y)
|
|||
void Ctrl::SyncMoves()
|
||||
{
|
||||
GuiLock __;
|
||||
Top *top = GetTop();
|
||||
if(!top)
|
||||
return;
|
||||
for(int i = 0; i < top->move.GetCount(); i++) {
|
||||
|
|
|
|||
131
uppsrc/CtrlCore/CtrlFrame.cpp
Normal file
131
uppsrc/CtrlCore/CtrlFrame.cpp
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
#include "CtrlCore.h"
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
namespace Upp {
|
||||
|
||||
Ctrl::Frame Ctrl::AllocFrames(int alloc)
|
||||
{
|
||||
Frame m;
|
||||
size_t sz0 = alloc * sizeof(Frame);
|
||||
size_t sz = sz0;
|
||||
m.frames = (Frame *)MemoryAllocSz(sz);
|
||||
m.multi.alloc = alloc + (int)((sz - sz0) / sizeof(Frame));
|
||||
return m;
|
||||
}
|
||||
|
||||
void Ctrl::InsertFrame(int i, CtrlFrame& fr)
|
||||
{
|
||||
GuiLock __;
|
||||
int fc = GetFrameCount();
|
||||
ASSERT(i <= fc);
|
||||
if(i == 0 && fc == 0) {
|
||||
frame.frame = &fr;
|
||||
multi_frame = false;
|
||||
}
|
||||
else {
|
||||
if(!multi_frame) {
|
||||
Frame h = AllocFrames(2);
|
||||
h.frames[0].frame = frame.frame;
|
||||
h.multi.count = 1;
|
||||
frame = h;
|
||||
multi_frame = true;
|
||||
}
|
||||
if(frame.multi.count + 1 > frame.multi.alloc) {
|
||||
Frame h = AllocFrames(3 * frame.multi.count / 2 + 1);
|
||||
memcpy(h.frames, frame.frames, i * sizeof(Frame));
|
||||
memcpy(h.frames + i + 1, frame.frames + i, (frame.multi.count - i) * sizeof(Frame));
|
||||
h.multi.count = frame.multi.count;
|
||||
FreeFrames();
|
||||
frame = h;
|
||||
}
|
||||
else
|
||||
memmove(frame.frames + i + 1, frame.frames + i, (frame.multi.count - i) * sizeof(Frame));
|
||||
frame.frames[i].frame = &fr;
|
||||
frame.multi.count++;
|
||||
}
|
||||
fr.FrameAdd(*this);
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::AddFrame(CtrlFrame& fr) {
|
||||
InsertFrame(GetFrameCount(), fr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveFrame(int i) {
|
||||
ASSERT(i < GetFrameCount());
|
||||
GetFrame(i).FrameRemove();
|
||||
if(multi_frame) {
|
||||
ASSERT(frame.multi.count > 1);
|
||||
memmove(frame.frames + i, frame.frames + i + 1, (frame.multi.count - i - 1) * sizeof(Frame));
|
||||
frame.multi.count--;
|
||||
if(frame.multi.count == 1) {
|
||||
CtrlFrame *h = frame.frames[0].frame;
|
||||
FreeFrames();
|
||||
multi_frame = false;
|
||||
frame.frame = h;
|
||||
}
|
||||
else
|
||||
if(3 * frame.multi.count < frame.multi.alloc) {
|
||||
Frame h = AllocFrames(3 * frame.multi.count / 2 + 1);
|
||||
memcpy(h.frames, frame.frames, frame.multi.count * sizeof(Frame));
|
||||
h.multi.count = frame.multi.count;
|
||||
FreeFrames();
|
||||
frame = h;
|
||||
}
|
||||
}
|
||||
else
|
||||
frame.frame = nullptr;
|
||||
if(GetFrameCount() == 0)
|
||||
SetFrame(NullFrame());
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::SetFrame(int i, CtrlFrame& fr) {
|
||||
GuiLock __;
|
||||
LLOG("SetFrame " << typeid(fr).name());
|
||||
while(GetFrameCount() <= i)
|
||||
AddFrame(NullFrame());
|
||||
Frame& f = GetFrame0(i);
|
||||
f.frame->FrameRemove();
|
||||
f.frame = &fr;
|
||||
fr.FrameAdd(*this);
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Ctrl::ClearFrames() {
|
||||
GuiLock __;
|
||||
int n = GetFrameCount();
|
||||
for(int i = 0; i < n; i++)
|
||||
GetFrame(i).FrameRemove();
|
||||
FreeFrames();
|
||||
multi_frame = false;
|
||||
frame.frame = &NullFrame();
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
}
|
||||
|
||||
int Ctrl::FindFrame(CtrlFrame& frm) const
|
||||
{
|
||||
GuiLock __;
|
||||
int n = GetFrameCount();
|
||||
for(int i = 0; i < n; i++)
|
||||
if(&GetFrame(i) == &frm)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveFrame(CtrlFrame& frm)
|
||||
{
|
||||
GuiLock __;
|
||||
int i = FindFrame(frm);
|
||||
if(i >= 0)
|
||||
RemoveFrame(i);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -7,8 +7,6 @@ namespace Upp {
|
|||
Ptr<Ctrl> Ctrl::focusCtrl;
|
||||
Ptr<Ctrl> Ctrl::focusCtrlWnd;
|
||||
Ptr<Ctrl> Ctrl::lastActiveWnd;
|
||||
Ptr<Ctrl> Ctrl::caretCtrl;
|
||||
Rect Ctrl::caretRect;
|
||||
bool Ctrl::ignorekeyup;
|
||||
|
||||
Ptr<Ctrl> Ctrl::defferedSetFocus;
|
||||
|
|
@ -116,7 +114,7 @@ bool Ctrl::HotKey(dword key)
|
|||
GuiLock __;
|
||||
LLOG("HotKey " << GetKeyDesc(key) << " at " << Name(this));
|
||||
if(!IsEnabled() || !IsVisible()) return false;
|
||||
for(Ptr<Ctrl> ctrl = firstchild; ctrl; ctrl = ctrl->next)
|
||||
for(Ptr<Ctrl> ctrl = GetFirstChild(); ctrl; ctrl = ctrl->GetNext())
|
||||
{
|
||||
LLOG("Trying HotKey " << GetKeyDesc(key) << " at " << Name(ctrl));
|
||||
if(ctrl->IsOpen() && ctrl->IsVisible() && ctrl->IsEnabled() && ctrl->HotKey(key))
|
||||
|
|
@ -158,8 +156,8 @@ void Ctrl::DoKillFocus(Ptr<Ctrl> pfocusCtrl, Ptr<Ctrl> nfocusCtrl)
|
|||
LLOG("LostFocus: " << Name(pfocusCtrl));
|
||||
pfocusCtrl->LostFocus();
|
||||
}
|
||||
if(pfocusCtrl && pfocusCtrl->parent && !pfocusCtrl->parent->destroying)
|
||||
pfocusCtrl->parent->ChildLostFocus();
|
||||
if(pfocusCtrl && pfocusCtrl->GetParent() && !pfocusCtrl->GetParent()->destroying)
|
||||
pfocusCtrl->GetParent()->ChildLostFocus();
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
|
|
@ -179,9 +177,9 @@ void Ctrl::DoSetFocus(Ptr<Ctrl> pfocusCtrl, Ptr<Ctrl> nfocusCtrl, bool activate)
|
|||
nfocusCtrl->GotFocus();
|
||||
nfocusCtrl->StateH(FOCUS);
|
||||
}
|
||||
if(focusCtrl == nfocusCtrl && nfocusCtrl && nfocusCtrl->parent &&
|
||||
!nfocusCtrl->parent->destroying)
|
||||
nfocusCtrl->parent->ChildGotFocus();
|
||||
if(focusCtrl == nfocusCtrl && nfocusCtrl && nfocusCtrl->GetParent() &&
|
||||
!nfocusCtrl->GetParent()->destroying)
|
||||
nfocusCtrl->GetParent()->ChildGotFocus();
|
||||
|
||||
SyncCaret();
|
||||
}
|
||||
|
|
@ -340,14 +338,6 @@ void Ctrl::DefferedFocusSync()
|
|||
}
|
||||
}
|
||||
|
||||
void Ctrl::RefreshCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
if(caretCtrl)
|
||||
caretCtrl->Refresh(caretCtrl->caretx, caretCtrl->carety,
|
||||
caretCtrl->caretcx, caretCtrl->caretcy);
|
||||
}
|
||||
|
||||
Ctrl *Ctrl::GetActiveWindow()
|
||||
{
|
||||
GuiLock __;
|
||||
|
|
@ -364,6 +354,61 @@ bool Ctrl::HasFocusDeep() const
|
|||
a = a->GetOwnerCtrl();
|
||||
return a && HasChildDeep(a);
|
||||
}
|
||||
Ptr<Ctrl> Ctrl::caretCtrl;
|
||||
Ptr<Ctrl> Ctrl::prevCaretCtrl;
|
||||
Rect Ctrl::caretRect;
|
||||
int Ctrl::WndCaretTime;
|
||||
bool Ctrl::WndCaretVisible;
|
||||
|
||||
void Ctrl::RefreshCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
if(prevCaretCtrl) {
|
||||
prevCaretCtrl->Refresh(caretRect);
|
||||
prevCaretCtrl = nullptr;
|
||||
}
|
||||
if(caretCtrl) {
|
||||
caretRect = caretCtrl->GetCaret();
|
||||
caretCtrl->Refresh(caretRect);
|
||||
prevCaretCtrl = caretCtrl;
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::AnimateCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
bool v = !(((msecs() - WndCaretTime) / GetCaretBlinkTime()) & 1);
|
||||
if(v != WndCaretVisible) {
|
||||
WndCaretVisible = v;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible);
|
||||
if(this == caretCtrl && WndCaretVisible)
|
||||
w.DrawRect(GetCaret(), InvertColor);
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
LLOG("SyncCaret");
|
||||
if(focusCtrl != caretCtrl) {
|
||||
LLOG("SyncCaret DO " << Upp::Name(caretCtrl) << " -> " << Upp::Name(focusCtrl));
|
||||
RefreshCaret();
|
||||
caretCtrl = focusCtrl;
|
||||
WndCaretTime = msecs();
|
||||
RefreshCaret();
|
||||
}
|
||||
else {
|
||||
if(caretCtrl && caretCtrl->GetCaret() != caretRect) {
|
||||
WndCaretTime = msecs();
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tuple<dword, const char *> KeyNames__[ ] = {
|
||||
{ K_A, tt_("key\vA") }, { K_B, tt_("key\vB") }, { K_C, tt_("key\vC") }, { K_D, tt_("key\vD") },
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ Image Ctrl::FrameMouseEventH(int event, Point p, int zdelta, dword keyflags)
|
|||
if(this_)
|
||||
LogMouseEvent("FRAME ", this, event, p, zdelta, keyflags);
|
||||
eventCtrl = this_;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent && this_)
|
||||
parent->ChildFrameMouseEvent(this, event, p, zdelta, keyflags);
|
||||
return this_ ? FrameMouseEvent(event, p, zdelta, keyflags) : Image();
|
||||
|
|
@ -93,6 +94,7 @@ Image Ctrl::MouseEvent0(int event, Point p, int zdelta, dword keyflags)
|
|||
bool pb = sPropagated;
|
||||
sPropagated = false;
|
||||
Image m = this_ ? MouseEvent(event, p, zdelta, keyflags) : Image();
|
||||
Ctrl *parent = this_ ? this_->GetParent() : NULL;
|
||||
if(event == MOUSEWHEEL && !sPropagated && this_ && parent)
|
||||
parent->ChildMouseEvent(this, event, p, zdelta, keyflags);
|
||||
sPropagated = pb;
|
||||
|
|
@ -108,6 +110,7 @@ Image Ctrl::MouseEventH(int event, Point p, int zdelta, dword keyflags)
|
|||
return Image::Arrow();
|
||||
if(this_)
|
||||
LogMouseEvent(NULL, this, event, p, zdelta, keyflags);
|
||||
Ctrl *parent = this_ ? this_->GetParent() : NULL;
|
||||
if(this_ && parent && event != MOUSEWHEEL)
|
||||
parent->ChildMouseEvent(this, event, p, zdelta, keyflags);
|
||||
return MouseEvent0(event, p, zdelta, keyflags);
|
||||
|
|
@ -115,6 +118,7 @@ Image Ctrl::MouseEventH(int event, Point p, int zdelta, dword keyflags)
|
|||
|
||||
void Ctrl::MouseWheel(Point p, int zd, dword kf)
|
||||
{
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent) {
|
||||
p += GetScreenView().TopLeft();
|
||||
Rect r = parent->GetScreenView();
|
||||
|
|
@ -128,6 +132,7 @@ void Ctrl::MouseWheel(Point p, int zd, dword kf)
|
|||
void Ctrl::ChildFrameMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildFrameMouseEvent(child, event, p, zdelta, keyflags);
|
||||
}
|
||||
|
|
@ -135,6 +140,7 @@ void Ctrl::ChildFrameMouseEvent(Ctrl *child, int event, Point p, int zdelta, dwo
|
|||
void Ctrl::ChildMouseEvent(Ctrl *child, int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->ChildMouseEvent(child, event, p, zdelta, keyflags);
|
||||
}
|
||||
|
|
@ -280,7 +286,7 @@ Ctrl *Ctrl::ChildFromPoint(Point& pt) const
|
|||
Rect view = GetView();
|
||||
if(view.Contains(p)) {
|
||||
Point vp = p - view.TopLeft();
|
||||
for(q = GetLastChild(); q; q = q->prev) {
|
||||
for(q = GetLastChild(); q; q = q->GetPrev()) {
|
||||
if(q->InView() && q->IsMouseActive()) {
|
||||
Rect r = q->GetRect();
|
||||
if(r.Contains(vp)) {
|
||||
|
|
@ -291,7 +297,7 @@ Ctrl *Ctrl::ChildFromPoint(Point& pt) const
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
for(q = GetLastChild(); q; q = q->prev) {
|
||||
for(q = GetLastChild(); q; q = q->GetPrev()) {
|
||||
if(q->InFrame() && q->IsMouseActive()) {
|
||||
Rect r = q->GetRect();
|
||||
if(r.Contains(p)) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ Rect Ctrl::GetRect() const
|
|||
Rect Ctrl::GetView() const
|
||||
{
|
||||
GuiLock __;
|
||||
return frame.GetCount() == 0 ? Rect(Size(rect.Size())) : Rect(frame[frame.GetCount() - 1].view);
|
||||
int n = GetFrameCount();
|
||||
return n == 0 ? Rect(Size(rect.Size())) : Rect(GetFrame0(n - 1).GetView());
|
||||
}
|
||||
|
||||
Size Ctrl::GetSize() const
|
||||
|
|
@ -72,6 +73,7 @@ Rect Ctrl::GetScreenRect() const
|
|||
{
|
||||
GuiLock __;
|
||||
Rect r = GetRect();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent) {
|
||||
Rect pr = inframe ? parent->GetScreenRect() : parent->GetScreenView();
|
||||
r = r + pr.TopLeft();
|
||||
|
|
@ -91,6 +93,7 @@ Rect Ctrl::GetVisibleScreenRect() const
|
|||
{
|
||||
GuiLock __;
|
||||
Rect r = GetRect();
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent) {
|
||||
Rect pr = inframe ? parent->GetVisibleScreenRect() : parent->GetVisibleScreenView();
|
||||
Rect pr1 = inframe ? parent->GetScreenRect() : parent->GetScreenView();
|
||||
|
|
@ -111,8 +114,8 @@ Size Ctrl::AddFrameSize(int cx, int cy) const
|
|||
{
|
||||
GuiLock __;
|
||||
Size sz = Size(cx, cy);
|
||||
for(int i = frame.GetCount() - 1; i >= 0; i--)
|
||||
frame[i].frame->FrameAddSize(sz);
|
||||
for(int i = GetFrameCount() - 1; i >= 0; i--)
|
||||
GetFrame0(i).frame->FrameAddSize(sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
|
@ -146,21 +149,22 @@ void Ctrl::SyncLayout(int force)
|
|||
Rect oview = GetView();
|
||||
Rect view = GetRect().Size();
|
||||
overpaint = OverPaint();
|
||||
for(int i = 0; i < frame.GetCount(); i++) {
|
||||
Frame& f = frame[i];
|
||||
int n = GetFrameCount();
|
||||
for(int i = 0; i < n; i++) {
|
||||
Frame& f = GetFrame0(i);
|
||||
f.frame->FrameLayout(view);
|
||||
if(view != Rect(f.view)) {
|
||||
f.view = view;
|
||||
if(view != f.GetView()) {
|
||||
f.SetView(view);
|
||||
refresh = true;
|
||||
}
|
||||
int q = f.frame->OverPaint();
|
||||
if(q > overpaint) overpaint = q;
|
||||
}
|
||||
if(oview.Size() != view.Size() || force > 1) {
|
||||
for(Ctrl *q = GetFirstChild(); q; q = q->next) {
|
||||
q->rect = q->CalcRect(rect, view);
|
||||
LLOG("Layout set rect " << q->Name() << " " << q->rect);
|
||||
q->SyncLayout(force > 1 ? force : 0);
|
||||
for(Ctrl& q : *this) {
|
||||
q.rect = q.CalcRect(rect, view);
|
||||
LLOG("Layout set rect " << q.Name() << " " << q.rect);
|
||||
q.SyncLayout(force > 1 ? force : 0);
|
||||
}
|
||||
Refresh();
|
||||
}
|
||||
|
|
@ -172,6 +176,20 @@ void Ctrl::SyncLayout(int force)
|
|||
RefreshFrame();
|
||||
}
|
||||
|
||||
void Ctrl::RefreshParentLayout()
|
||||
{
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->RefreshLayout();
|
||||
}
|
||||
|
||||
void Ctrl::UpdateParentLayout()
|
||||
{
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
parent->UpdateLayout();
|
||||
}
|
||||
|
||||
int Ctrl::FindMoveCtrl(const VectorMap<Ctrl *, MoveCtrl>& m, Ctrl *x)
|
||||
{
|
||||
int q = m.Find(x);
|
||||
|
|
@ -188,10 +206,11 @@ void Ctrl::SetPos0(LogPos p, bool _inframe)
|
|||
{
|
||||
GuiLock __;
|
||||
if(p == pos && inframe == _inframe) return;
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent && !IsDHCtrl()) {
|
||||
if(!globalbackbuffer) {
|
||||
Rect from = GetRect().Size();
|
||||
Top *top = GetTopRect(from, true)->top;
|
||||
Top *top = GetTopRect(from, true)->GetTop();
|
||||
if(top) {
|
||||
LTIMING("SetPos0 MoveCtrl");
|
||||
pos = p;
|
||||
|
|
@ -227,6 +246,7 @@ void Ctrl::UpdateRect0(bool sync)
|
|||
{
|
||||
GuiLock __;
|
||||
LTIMING("UpdateRect0");
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
rect = CalcRect(parent->GetRect(), parent->GetView());
|
||||
else {
|
||||
|
|
@ -247,12 +267,13 @@ void Ctrl::UpdateRect(bool sync)
|
|||
{
|
||||
GuiLock __;
|
||||
UpdateRect0(sync);
|
||||
if(parent) RefreshFrame();
|
||||
if(GetParent()) RefreshFrame();
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::SetPos(LogPos p, bool _inframe)
|
||||
{
|
||||
GuiLock __;
|
||||
Ctrl *parent = GetParent();
|
||||
if(p != pos || inframe != _inframe) {
|
||||
if(parent || !IsOpen())
|
||||
SetPos0(p, _inframe);
|
||||
|
|
@ -336,93 +357,6 @@ void Ctrl::SetFrameRectY(int y, int cy) {
|
|||
SetFramePosY(PosTop(y, cy));
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::SetFrame(int i, CtrlFrame& fr) {
|
||||
GuiLock __;
|
||||
LLOG("SetFrame " << typeid(fr).name());
|
||||
while(frame.GetCount() <= i)
|
||||
frame.Add().frame = &NullFrame();
|
||||
frame[i].frame->FrameRemove();
|
||||
frame[i].frame = &fr;
|
||||
fr.FrameAdd(*this);
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
return *this;
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::AddFrame(CtrlFrame& fr) {
|
||||
GuiLock __;
|
||||
LLOG("AddFrame " << typeid(fr).name());
|
||||
frame.Add().frame = &fr;
|
||||
fr.FrameAdd(*this);
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Ctrl::ClearFrames() {
|
||||
GuiLock __;
|
||||
for(int i = 0; i < frame.GetCount(); i++)
|
||||
frame[i].frame->FrameRemove();
|
||||
frame.Clear();
|
||||
frame.Add().frame = &NullFrame();
|
||||
RefreshFrame();
|
||||
SyncLayout();
|
||||
}
|
||||
|
||||
void Ctrl::RemoveFrame(int i) {
|
||||
GuiLock __;
|
||||
int n = frame.GetCount();
|
||||
Mitor<Frame> m;
|
||||
if(n > 1)
|
||||
for(int q = 0; q < n; q++) {
|
||||
if(q != i)
|
||||
m.Add().frame = frame[q].frame;
|
||||
else
|
||||
frame[q].frame->FrameRemove();
|
||||
}
|
||||
frame = pick(m);
|
||||
if(frame.GetCount() == 0)
|
||||
frame.Add().frame = &NullFrame();
|
||||
RefreshFrame();
|
||||
SyncLayout();
|
||||
}
|
||||
|
||||
int Ctrl::FindFrame(CtrlFrame& frm)
|
||||
{
|
||||
GuiLock __;
|
||||
for(int i = 0; i < frame.GetCount(); i++)
|
||||
if(frame[i].frame == &frm)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::RemoveFrame(CtrlFrame& frm)
|
||||
{
|
||||
GuiLock __;
|
||||
int i = FindFrame(frm);
|
||||
if(i >= 0)
|
||||
RemoveFrame(i);
|
||||
}
|
||||
|
||||
void Ctrl::InsertFrame(int i, CtrlFrame& fr)
|
||||
{
|
||||
GuiLock __;
|
||||
ASSERT(i >= 0 && i <= frame.GetCount());
|
||||
int n = frame.GetCount();
|
||||
Mitor<Frame> m;
|
||||
if(n >= 1)
|
||||
for(int q = 0; q < n; q++) {
|
||||
if(q == i) m.Add().frame = &fr;
|
||||
m.Add().frame = frame[q].frame;
|
||||
}
|
||||
if(i == n)
|
||||
m.Add().frame = &fr;
|
||||
frame = pick(m);
|
||||
fr.FrameAdd(*this);
|
||||
SyncLayout();
|
||||
RefreshFrame();
|
||||
}
|
||||
|
||||
Ctrl& Ctrl::LeftPos(int a, int size) {
|
||||
return SetPosX(PosLeft(a, size));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ void Ctrl::Create(Ctrl *owner, bool popup)
|
|||
ASSERT(!IsChild() && !IsOpen());
|
||||
LLOG("Ungrab1");
|
||||
|
||||
top = new Top;
|
||||
Top *top = new Top;
|
||||
SetTop(top);
|
||||
top->window = gtk_window_new(popup && owner ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
|
||||
top->owner = owner;
|
||||
|
||||
|
|
@ -111,12 +112,13 @@ void Ctrl::WndDestroy()
|
|||
if(HasFocusDeep() || !GetFocusCtrl())
|
||||
activeCtrl = owner;
|
||||
}
|
||||
Top *top = GetTop();
|
||||
if(top->im_context)
|
||||
g_object_unref(top->im_context);
|
||||
gtk_widget_destroy(top->window);
|
||||
isopen = false;
|
||||
popup = false;
|
||||
delete top;
|
||||
DeleteTop();
|
||||
top = NULL;
|
||||
int q = FindCtrl(this);
|
||||
if(q >= 0)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,20 @@ void Ctrl::InstallPanicBox()
|
|||
{
|
||||
}
|
||||
|
||||
GdkWindow *Ctrl::gdk() const
|
||||
{
|
||||
const Top *top = GetTop();
|
||||
return top ? gtk_widget_get_window(top->window) : NULL;
|
||||
}
|
||||
|
||||
GtkWindow *Ctrl::gtk() const
|
||||
{
|
||||
const Top *top = GetTop();
|
||||
return top ? (GtkWindow *)top->window : NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -95,8 +95,6 @@ _DBG_
|
|||
static Vector<Ptr<Ctrl>> activePopup; // created with 'activate' flag - usually menu
|
||||
static Vector<Ptr<Ctrl>> visiblePopup; // any popup visible on screen
|
||||
static Vector<Win> wins;
|
||||
static int WndCaretTime;
|
||||
static bool WndCaretVisible;
|
||||
static Ptr<Ctrl> grabwindow;
|
||||
static Ptr<Ctrl> grabpopup;
|
||||
static Ptr<Ctrl> sel_ctrl;
|
||||
|
|
@ -115,7 +113,6 @@ _DBG_
|
|||
void ReleasePopupCapture();
|
||||
|
||||
static void FocusSync();
|
||||
static void AnimateCaret();
|
||||
static gboolean TimeHandler(GtkWidget *);
|
||||
static void InvalidateMousePos();
|
||||
static void StopGrabPopup();
|
||||
|
|
@ -199,6 +196,8 @@ public: // really private:
|
|||
static int SCL(int x) { return scale * x; }
|
||||
static Rect SCL(int x, int y, int cx, int cy) { return RectC(SCL(x), SCL(y), SCL(cx), SCL(cy)); }
|
||||
static double LSC(int x) { return (double)x / scale; }
|
||||
|
||||
static int GetCaretBlinkTime() { return 500; }
|
||||
|
||||
public:
|
||||
static void EndSession() {}
|
||||
|
|
@ -210,8 +209,8 @@ public:
|
|||
static guint32 CurrentTime;
|
||||
static GEvent CurrentEvent;
|
||||
|
||||
GdkWindow *gdk() const { return top ? gtk_widget_get_window(top->window) : NULL; }
|
||||
GtkWindow *gtk() const { return top ? (GtkWindow *)top->window : NULL; }
|
||||
GdkWindow *gdk() const;
|
||||
GtkWindow *gtk() const;
|
||||
|
||||
static GdkFilterReturn RootKeyFilter(GdkXEvent *xevent, GdkEvent *event, gpointer data);
|
||||
|
||||
|
|
|
|||
|
|
@ -124,14 +124,16 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
|
|||
iw.DrawImage(1, 1, sz.cx, sz.cy, sample);
|
||||
dnd_icon = iw;
|
||||
}
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
gtk_drag_begin_with_coordinates(w->top->window, list, GdkDragAction(gdk_actions),
|
||||
GetMouseLeft() ? 1 : GetMouseMiddle() ? 2 : 3,
|
||||
CurrentEvent.event, -1, -1);
|
||||
#else
|
||||
gtk_drag_begin(w->top->window, list, GdkDragAction(gdk_actions),
|
||||
GetMouseLeft() ? 1 : GetMouseMiddle() ? 2 : 3, CurrentEvent.event);
|
||||
#endif
|
||||
Top *top = w->GetTop();
|
||||
if(top)
|
||||
#if GTK_CHECK_VERSION(3, 10, 0)
|
||||
gtk_drag_begin_with_coordinates(top->window, list, GdkDragAction(gdk_actions),
|
||||
GetMouseLeft() ? 1 : GetMouseMiddle() ? 2 : 3,
|
||||
CurrentEvent.event, -1, -1);
|
||||
#else
|
||||
gtk_drag_begin(top->window, list, GdkDragAction(gdk_actions),
|
||||
GetMouseLeft() ? 1 : GetMouseMiddle() ? 2 : 3, CurrentEvent.event);
|
||||
#endif
|
||||
while(dnd_source && GetTopCtrls().GetCount())
|
||||
ProcessEvents();
|
||||
dnd_source_data = NULL;
|
||||
|
|
@ -329,6 +331,9 @@ gboolean Ctrl::GtkDragDrop(GtkWidget *widget, GdkDragContext *context, gint x, g
|
|||
|
||||
void Ctrl::DndInit()
|
||||
{
|
||||
Top *top = GetTop();
|
||||
if(!top)
|
||||
return;
|
||||
GtkWidget *w = top->window;
|
||||
gpointer id = (gpointer)(uintptr_t)top->id;
|
||||
g_signal_connect(w, "drag-begin", G_CALLBACK(GtkDragBegin), id);
|
||||
|
|
@ -345,6 +350,7 @@ void Ctrl::DndInit()
|
|||
|
||||
void Ctrl::DndExit()
|
||||
{
|
||||
Top *top = GetTop();
|
||||
if(top)
|
||||
gtk_drag_dest_unset(top->window);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -135,10 +135,13 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
|||
case GDK_FOCUS_CHANGE:
|
||||
p->CancelPreedit();
|
||||
if(p) {
|
||||
if(((GdkEventFocus *)event)->in)
|
||||
gtk_im_context_focus_in(p->top->im_context);
|
||||
else
|
||||
gtk_im_context_focus_out(p->top->im_context);
|
||||
Top *top = p->GetTop();
|
||||
if(top) {
|
||||
if(((GdkEventFocus *)event)->in)
|
||||
gtk_im_context_focus_in(top->im_context);
|
||||
else
|
||||
gtk_im_context_focus_out(top->im_context);
|
||||
}
|
||||
AddEvent(user_data, EVENT_FOCUS_CHANGE, value, event);
|
||||
}
|
||||
return false;
|
||||
|
|
@ -181,8 +184,11 @@ gboolean Ctrl::GtkEvent(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
|||
value << (int) key->keyval << (int) key->hardware_keycode;
|
||||
if(pressed) {
|
||||
p = GetTopCtrlFromId(user_data);
|
||||
if(p && gtk_im_context_filter_keypress(p->top->im_context, key))
|
||||
return true;
|
||||
if(p) {
|
||||
Top *top = p->GetTop();
|
||||
if(top && gtk_im_context_filter_keypress(top->im_context, key))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GDK_CONFIGURE: {
|
||||
|
|
@ -344,7 +350,9 @@ void Ctrl::IMLocation(Ctrl *w)
|
|||
gr.y = LSC(e.top - q.top);
|
||||
gr.width = LSC(e.GetWidth());
|
||||
gr.height = LSC(e.GetHeight());
|
||||
gtk_im_context_set_cursor_location(w->top->im_context, &gr);
|
||||
Top *top = w->GetTop();
|
||||
if(top)
|
||||
gtk_im_context_set_cursor_location(top->im_context, &gr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,15 +33,18 @@ void TopWindow::SyncSizeHints()
|
|||
m.max_width = LSC(sz.cx);
|
||||
m.max_height = LSC(sz.cy);
|
||||
gtk_window_set_resizable(gtk(), sizeable);
|
||||
gtk_window_set_geometry_hints(gtk(), top->window, &m,
|
||||
GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE));
|
||||
gtk_widget_set_size_request(top->window, m.min_width, m.min_height);
|
||||
Top *top = GetTop();
|
||||
if(top) {
|
||||
gtk_window_set_geometry_hints(gtk(), top->window, &m,
|
||||
GdkWindowHints(GDK_HINT_MIN_SIZE|GDK_HINT_MAX_SIZE));
|
||||
gtk_widget_set_size_request(top->window, m.min_width, m.min_height);
|
||||
}
|
||||
}
|
||||
|
||||
void TopWindow::SyncTitle()
|
||||
{
|
||||
GuiLock __;
|
||||
if(top)
|
||||
if(GetTop())
|
||||
gtk_window_set_title(gtk(), FromUnicode(title, CHARSET_UTF8));
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +130,9 @@ void TopWindow::Open(Ctrl *owner)
|
|||
CenterRect(owner);
|
||||
IgnoreMouseUp();
|
||||
Create(owner, false);
|
||||
g_signal_connect(top->window, "window-state-event", G_CALLBACK(StateEvent), this);
|
||||
Top *top = GetTop();
|
||||
if(top)
|
||||
g_signal_connect(top->window, "window-state-event", G_CALLBACK(StateEvent), this);
|
||||
SyncSizeHints();
|
||||
SyncCaption();
|
||||
PlaceFocus();
|
||||
|
|
|
|||
|
|
@ -14,9 +14,6 @@ Vector<Ctrl::Win> Ctrl::wins;
|
|||
|
||||
Ptr<Ctrl> Ctrl::activeCtrl;
|
||||
|
||||
int Ctrl::WndCaretTime;
|
||||
bool Ctrl::WndCaretVisible;
|
||||
|
||||
bool Ctrl::invalids;
|
||||
|
||||
int Ctrl::FindId(int id)
|
||||
|
|
@ -84,7 +81,7 @@ void Ctrl::SetMouseCursor(const Image& image)
|
|||
else
|
||||
topctrl = GetActiveCtrl();
|
||||
if(topctrl)
|
||||
top = topctrl->top;
|
||||
top = topctrl->GetTop();
|
||||
if(top && id != top->cursor_id) {
|
||||
top->cursor_id = id;
|
||||
int64 aux = image.GetAuxData();
|
||||
|
|
@ -122,6 +119,7 @@ void Ctrl::SetMouseCursor(const Image& image)
|
|||
Ctrl *Ctrl::GetOwner()
|
||||
{
|
||||
GuiLock __;
|
||||
Top *top = GetTop();
|
||||
return IsOpen() ? top->owner : NULL;
|
||||
}
|
||||
|
||||
|
|
@ -150,52 +148,6 @@ void Ctrl::UnregisterSystemHotKey(int id)
|
|||
|
||||
#endif
|
||||
|
||||
void Ctrl::AnimateCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
int v = !(((msecs() - WndCaretTime) / 500) & 1);
|
||||
if(v != WndCaretVisible) {
|
||||
WndCaretVisible = v;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible);
|
||||
if(this == caretCtrl && WndCaretVisible)
|
||||
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetCaret " << Name());
|
||||
if(this == caretCtrl)
|
||||
RefreshCaret();
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
if(this == caretCtrl) {
|
||||
WndCaretTime = msecs();
|
||||
RefreshCaret();
|
||||
AnimateCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
LLOG("SyncCaret");
|
||||
if(focusCtrl != caretCtrl) {
|
||||
LLOG("SyncCaret DO " << Upp::Name(caretCtrl) << " -> " << Upp::Name(focusCtrl));
|
||||
RefreshCaret();
|
||||
caretCtrl = focusCtrl;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
Rect Ctrl::GetWndScreenRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
|
|
@ -213,7 +165,9 @@ void Ctrl::WndShow(bool b)
|
|||
{
|
||||
GuiLock __;
|
||||
LLOG("WndShow " << Name() << ", " << b);
|
||||
if(IsOpen()) {
|
||||
Top *top = GetTop();
|
||||
if(IsOpen() && top) {
|
||||
|
||||
if(b)
|
||||
gtk_widget_show_now(top->window);
|
||||
else
|
||||
|
|
@ -224,6 +178,7 @@ void Ctrl::WndShow(bool b)
|
|||
|
||||
bool Ctrl::IsWndOpen() const {
|
||||
GuiLock __;
|
||||
const Top *top = GetTop();
|
||||
return top && top->window && gtk_widget_get_window(top->window);
|
||||
}
|
||||
|
||||
|
|
@ -400,12 +355,13 @@ void Ctrl::DoCancelPreedit()
|
|||
{
|
||||
if(!focusCtrl)
|
||||
return;
|
||||
if(focusCtrl->top)
|
||||
Top *top = focusCtrl->GetTop();
|
||||
if(top)
|
||||
focusCtrl->HidePreedit();
|
||||
if(focusCtrl->top) {
|
||||
gtk_im_context_reset(focusCtrl->top->im_context);
|
||||
gtk_im_context_focus_out(focusCtrl->top->im_context);
|
||||
gtk_im_context_focus_in(focusCtrl->top->im_context);
|
||||
if(top) {
|
||||
gtk_im_context_reset(top->im_context);
|
||||
gtk_im_context_focus_out(top->im_context);
|
||||
gtk_im_context_focus_in(top->im_context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -458,7 +414,8 @@ bool Ctrl::SweepConfigure(bool wait)
|
|||
FetchEvents(wait);
|
||||
for(int i = 0; i < Events.GetCount() && this_; i++) {
|
||||
GEvent& e = Events[i];
|
||||
if(e.type == GDK_CONFIGURE && this_ && top->id == e.windowid) {
|
||||
Top *top = GetTop();
|
||||
if(e.type == GDK_CONFIGURE && this_ && top && top->id == e.windowid) {
|
||||
Rect rect = e.value;
|
||||
LLOG("SweepConfigure " << rect);
|
||||
if(GetRect() != rect)
|
||||
|
|
@ -495,6 +452,7 @@ void Ctrl::WndEnable(bool b)
|
|||
{
|
||||
GuiLock __;
|
||||
if(IsOpen()) {
|
||||
Top *top = GetTop();
|
||||
gtk_widget_set_sensitive(top->window, b);
|
||||
StateH(ENABLE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,8 +150,7 @@ void WinMetaFile::Serialize(Stream& s) {
|
|||
Clear();
|
||||
s % size;
|
||||
if(size) {
|
||||
Buffer<byte> buffer(size);
|
||||
s.SerializeRaw(buffer, size);
|
||||
String buffer = s.GetAll(size);
|
||||
HENHMETAFILE hemf = ::SetEnhMetaFileBits(size, buffer);
|
||||
Attach(hemf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,6 +273,7 @@ void TopWindow::Open(Ctrl *owner)
|
|||
GuiLock __;
|
||||
LLOG("TopWindow::Open(Ctrl) -> " << UPP::Name(owner));
|
||||
Open(owner ? owner->GetTopCtrl()->GetHWND() : NULL);
|
||||
Top *top = GetTop();
|
||||
if(IsOpen() && top)
|
||||
top->owner = owner;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ private:
|
|||
bool fullscreen;
|
||||
|
||||
byte center:2;
|
||||
|
||||
int exitcode = 0;
|
||||
|
||||
void PlaceFocus();
|
||||
void ActiveFocus0(Ctrl& ctrl);
|
||||
|
|
@ -91,6 +93,8 @@ private:
|
|||
GUIPLATFORM_TOPWINDOW_DECLS
|
||||
#endif
|
||||
|
||||
friend class Ctrl;
|
||||
|
||||
public:
|
||||
virtual void ShutdownWindow();
|
||||
|
||||
|
|
@ -125,6 +129,8 @@ public:
|
|||
int Execute();
|
||||
bool ExecuteOK() { return Execute() == IDOK; }
|
||||
bool ExecuteCancel() { return Execute() == IDCANCEL; }
|
||||
|
||||
int GetExitCode() const { return exitcode; }
|
||||
|
||||
void Minimize(bool effect = false);
|
||||
void Maximize(bool effect = false);
|
||||
|
|
|
|||
|
|
@ -76,44 +76,6 @@ void GuiPlatformAfterMenuPopUp()
|
|||
{
|
||||
}
|
||||
|
||||
#if WINCARET
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
Rect cr;
|
||||
cr.Clear();
|
||||
if(focusCtrl && focusCtrl->IsVisible()) {
|
||||
bool inframe = focusCtrl->InFrame();
|
||||
cr = focusCtrl->GetScreenView();
|
||||
cr = RectC(focusCtrl->caretx + cr.left, focusCtrl->carety + cr.top,
|
||||
focusCtrl->caretcx, focusCtrl->caretcy) & cr;
|
||||
for(Ctrl *q = focusCtrl->GetParent(); q; q = q->GetParent()) {
|
||||
cr &= inframe ? q->GetScreenRect() : q->GetScreenView();
|
||||
inframe = q->InFrame();
|
||||
}
|
||||
}
|
||||
if(focusCtrl != caretCtrl || cr != caretRect) {
|
||||
LLOG("Do SyncCaret focusCtrl: " << UPP::Name(focusCtrl)
|
||||
<< ", caretCtrl: " << UPP::Name(caretCtrl)
|
||||
<< ", cr: " << cr);
|
||||
WndDestroyCaret();
|
||||
if(focusCtrl && !cr.IsEmpty())
|
||||
focusCtrl->GetTopCtrl()->WndCreateCaret(cr);
|
||||
caretCtrl = focusCtrl;
|
||||
caretRect = cr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
String Ctrl::Name() const {
|
||||
GuiLock __;
|
||||
String s = Name0();
|
||||
|
|
|
|||
|
|
@ -4,15 +4,6 @@ private:
|
|||
bool activex:1;
|
||||
bool isdhctrl:1;
|
||||
|
||||
#if WINCARET
|
||||
static void WndDestroyCaret();
|
||||
void WndCreateCaret(const Rect& cr);
|
||||
#else
|
||||
static int WndCaretTime;
|
||||
static bool WndCaretVisible;
|
||||
static void AnimateCaret();
|
||||
#endif
|
||||
|
||||
static bool GetMsg(MSG& msg);
|
||||
|
||||
static bool DumpMessage(Ctrl *w, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
|
@ -66,7 +57,7 @@ public:
|
|||
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
|
||||
virtual bool PreprocessMessage(MSG& msg);
|
||||
|
||||
HWND GetHWND() const { return parent ? NULL : top ? top->hwnd : NULL; }
|
||||
HWND GetHWND() const { return GetParent() ? NULL : GetTop() ? GetTop()->hwnd : NULL; }
|
||||
HWND GetOwnerHWND() const;
|
||||
|
||||
static Ctrl *CtrlFromHWND(HWND hwnd);
|
||||
|
|
|
|||
|
|
@ -68,13 +68,14 @@ void Ctrl::DoCancelPreedit()
|
|||
{
|
||||
if(!focusCtrlWnd)
|
||||
return;
|
||||
if(focusCtrlWnd->top)
|
||||
Top *top = focusCtrl->GetTop();
|
||||
if(top)
|
||||
focusCtrl->HidePreedit();
|
||||
if(focusCtrlWnd->top && focusCtrlWnd->top->hwnd) {
|
||||
HIMC himc = ImmGetContext(focusCtrlWnd->top->hwnd);
|
||||
if(top && top->hwnd) {
|
||||
HIMC himc = ImmGetContext(top->hwnd);
|
||||
if(himc && ImmGetOpenStatus(himc)) {
|
||||
ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
|
||||
ImmReleaseContext(focusCtrlWnd->top->hwnd, himc);
|
||||
ImmReleaseContext(top->hwnd, himc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ Vector<Ctrl *> Ctrl::GetTopCtrls()
|
|||
Vector<Ctrl *> v;
|
||||
VectorMap< HWND, Ptr<Ctrl> >& w = Windows();
|
||||
for(int i = 0; i < w.GetCount(); i++)
|
||||
if(w.GetKey(i) && w[i] && !w[i]->parent)
|
||||
if(w.GetKey(i) && w[i] && !w[i]->GetParent())
|
||||
v.Add(w[i]);
|
||||
return v;
|
||||
}
|
||||
|
|
@ -472,7 +472,8 @@ void Ctrl::Create(HWND parent, DWORD style, DWORD exstyle, bool savebits, int sh
|
|||
Rect r = GetRect();
|
||||
AdjustWindowRectEx(r, style, FALSE, exstyle);
|
||||
isopen = true;
|
||||
top = new Top;
|
||||
Top *top = new Top;
|
||||
SetTop(top);
|
||||
ASSERT(!parent || IsWindow(parent));
|
||||
style &= ~WS_VISIBLE;
|
||||
dropshadow = false;
|
||||
|
|
@ -501,11 +502,11 @@ void ReleaseUDropTarget(UDropTarget *dt);
|
|||
void Ctrl::WndFree()
|
||||
{
|
||||
GuiLock __;
|
||||
if(!top) return;
|
||||
Top *top = GetTop();
|
||||
RevokeDragDrop(GetHWND());
|
||||
if(!top) return;
|
||||
ReleaseUDropTarget(top->dndtgt);
|
||||
isopen = false;
|
||||
if(!top) return;
|
||||
HWND owner = GetWindow(top->hwnd, GW_OWNER);// CXL 31.10.2003 z DoRemove
|
||||
bool focus = ::GetFocus() == top->hwnd;
|
||||
LLOG("Ctrl::WndDestroy owner " << (void *)owner
|
||||
|
|
@ -519,13 +520,13 @@ void Ctrl::WndFree()
|
|||
::SetFocus(owner);
|
||||
}
|
||||
LLOG(LOG_END << "//Ctrl::WndFree() in " <<UPP::Name(this));
|
||||
delete top;
|
||||
top = NULL;
|
||||
DeleteTop();
|
||||
}
|
||||
|
||||
void Ctrl::WndDestroy()
|
||||
{
|
||||
GuiLock __;
|
||||
Top *top = GetTop();
|
||||
if(top && top->hwnd) {
|
||||
HWND hwnd = top->hwnd;
|
||||
WndFree();
|
||||
|
|
@ -563,14 +564,16 @@ sWinMsg[] = {
|
|||
void Ctrl::NcCreate(HWND hwnd)
|
||||
{
|
||||
GuiLock __;
|
||||
if(!parent)
|
||||
Top *top = GetTop();
|
||||
if(top)
|
||||
top->hwnd = hwnd;
|
||||
}
|
||||
|
||||
void Ctrl::NcDestroy()
|
||||
{
|
||||
GuiLock __;
|
||||
if(!parent)
|
||||
Top *top = GetTop();
|
||||
if(top)
|
||||
WndFree();
|
||||
}
|
||||
|
||||
|
|
@ -839,80 +842,6 @@ void Ctrl::GuiSleep(int ms)
|
|||
EnterGuiMutex(level);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void Ctrl::WndDestroyCaret()
|
||||
{
|
||||
DLOG("Ctrl::WndDestroyCaret()");
|
||||
::DestroyCaret();
|
||||
}
|
||||
|
||||
void Ctrl::WndCreateCaret(const Rect& cr)
|
||||
{
|
||||
GuiLock __;
|
||||
DLOG("Ctrl::WndCreateCaret(" << cr << ") in " << UPP::Name(this));
|
||||
HWND hwnd = GetHWND();
|
||||
if(!hwnd) return;
|
||||
Rect r;
|
||||
::GetClientRect(hwnd, r);
|
||||
Point p = r.TopLeft();
|
||||
::ClientToScreen(hwnd, p);
|
||||
::CreateCaret(hwnd, NULL, cr.Width(), cr.Height());
|
||||
::SetCaretPos(cr.left - p.x, cr.top - p.y);
|
||||
::ShowCaret(hwnd);
|
||||
}
|
||||
#else
|
||||
|
||||
int Ctrl::WndCaretTime;
|
||||
bool Ctrl::WndCaretVisible;
|
||||
|
||||
void Ctrl::AnimateCaret()
|
||||
{
|
||||
GuiLock __;
|
||||
bool v = !(((msecs() - WndCaretTime) / GetCaretBlinkTime()) & 1);
|
||||
if(v != WndCaretVisible) {
|
||||
WndCaretVisible = v;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible);
|
||||
if(this == caretCtrl && WndCaretVisible)
|
||||
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
LLOG("SetCaret " << Name() << " " << RectC(x, y, cx, cy));
|
||||
if(this == caretCtrl)
|
||||
RefreshCaret();
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
if(this == caretCtrl) {
|
||||
WndCaretTime = msecs();
|
||||
RefreshCaret();
|
||||
AnimateCaret();
|
||||
}
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret() {
|
||||
GuiLock __;
|
||||
LLOG("SyncCaret");
|
||||
if(focusCtrl != caretCtrl) {
|
||||
LLOG("SyncCaret DO " << Upp::Name(caretCtrl) << " -> " << Upp::Name(focusCtrl));
|
||||
RefreshCaret();
|
||||
caretCtrl = focusCtrl;
|
||||
RefreshCaret();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Rect Ctrl::GetWndScreenRect() const
|
||||
{
|
||||
GuiLock __;
|
||||
|
|
@ -947,7 +876,7 @@ void Ctrl::SetAlpha(byte alpha)
|
|||
{
|
||||
GuiLock __;
|
||||
HWND hwnd = GetHWND();
|
||||
if(!IsAlphaSupported() || parent || !top || !hwnd)
|
||||
if(!IsAlphaSupported() || GetParent() || !top || !hwnd)
|
||||
return;
|
||||
if(alpha == 255) {
|
||||
SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x80000);
|
||||
|
|
@ -1183,14 +1112,10 @@ void Ctrl::WndUpdate(const Rect& r)
|
|||
if(GetUpdateRgn(hwnd, hrgn, FALSE) != NULLREGION) {
|
||||
SelectClipRgn(hdc, hrgn);
|
||||
SystemDraw draw(hdc);
|
||||
bool hcr = focusCtrl && focusCtrl->GetTopCtrl() == top &&
|
||||
caretRect.Intersects(r + top->GetRect().TopLeft());
|
||||
if(hcr) ::HideCaret(hwnd);
|
||||
draw.Clip(r);
|
||||
top->UpdateArea(draw, r);
|
||||
ValidateRect(hwnd, r);
|
||||
SelectClipRgn(hdc, NULL);
|
||||
if(hcr) ::ShowCaret(hwnd);
|
||||
}
|
||||
ReleaseDC(hwnd, hdc);
|
||||
DeleteObject(hrgn);
|
||||
|
|
@ -1201,14 +1126,8 @@ void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
|
|||
{
|
||||
GuiLock __;
|
||||
LLOG("WndScrollView " << UPP::Name(this));
|
||||
if(caretCtrl && caretCtrl->GetTopCtrl() == this) {
|
||||
#if WINCARET
|
||||
WndDestroyCaret();
|
||||
#else
|
||||
if(caretCtrl && caretCtrl->GetTopCtrl() == this)
|
||||
RefreshCaret();
|
||||
#endif
|
||||
caretRect.Clear();
|
||||
}
|
||||
#ifdef PLATFORM_WINCE
|
||||
::ScrollWindowEx(GetHWND(), dx, dy, r, r, NULL, NULL, 0);
|
||||
#else
|
||||
|
|
@ -1234,6 +1153,7 @@ void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, boo
|
|||
popup = false;
|
||||
Ctrl *q = owner ? owner->GetTopCtrl() : GetActiveCtrl();
|
||||
PopUpHWND(q ? q->GetHWND() : NULL, savebits, activate, dropshadow, topmost);
|
||||
Top *top = GetTop();
|
||||
if(top) top->owner = owner;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,9 +54,9 @@
|
|||
|
||||
#define LAYOUT(nm, x, y) template <class L, class D> \
|
||||
void InitLayout(UPP::Ctrl& parent, L& layout, D& uts, nm##__layid&) { \
|
||||
parent.LayoutId(#nm);
|
||||
#define UNTYPED(var, param) uts.var.param; uts.var.LayoutId(#var); parent.Add(uts.var);
|
||||
#define ITEM(clss, var, param) layout.var.param; layout.var.LayoutId(#var); parent.Add(layout.var);
|
||||
parent.LayoutIdLiteral(#nm);
|
||||
#define UNTYPED(var, param) uts.var.param; uts.var.LayoutIdLiteral(#var); parent.Add(uts.var);
|
||||
#define ITEM(clss, var, param) layout.var.param; layout.var.LayoutIdLiteral(#var); parent.Add(layout.var);
|
||||
#define END_LAYOUT }
|
||||
|
||||
#include LAYOUTFILE
|
||||
|
|
|
|||
|
|
@ -1978,33 +1978,6 @@ pointer to it.&]
|
|||
its descendants.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:SetCaret`(int`,int`,int`,int`):%- [@(0.0.255) void]_[* SetCaret]([@(0.0.255) i
|
||||
nt]_[*@3 x], [@(0.0.255) int]_[*@3 y], [@(0.0.255) int]_[*@3 cx], [@(0.0.255) int]_[*@3 cy])&]
|
||||
[s2;b17;a17; Place caret rectangle block at given position in view
|
||||
area. Caret rectangle is full flashing box and usually indicates
|
||||
place where text is to entered. Ctrl can have just one caret.
|
||||
Only Ctrl with focus has its caret displayed (also means that
|
||||
you do not need to remove caret when Ctrl goes out of focus).&]
|
||||
[s7;i1120;a17; [%-*C@3 x]-|X position.&]
|
||||
[s7;i1120;a17; [%-*C@3 y]-|Y position.&]
|
||||
[s7;i1120;a17; [%-*C@3 cx]-|Horizontal size.&]
|
||||
[s7;i1120;a17; [%-*C@3 cy]-|Vertical size.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:SetCaret`(const `:`:Rect`&`):%- [@(0.0.255) void]_[* SetCaret]([@(0.0.255) con
|
||||
st]_[_^`:`:Rect^ Rect][@(0.0.255) `&]_[*@3 r])&]
|
||||
[s2;b17;a17; Place caret rectangle block at given position in view
|
||||
area. Caret rectangle is full flashing box and usually indicates
|
||||
place where text is to entered. Ctrl can have just one caret.
|
||||
Only Ctrl with focus has its caret displayed (also means that
|
||||
you do not need to remove caret when Ctrl goes out of focus).&]
|
||||
[s7;i1120;a17; [%-*C@3 r]-|Caret block rectangle.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:KillCaret`(`):%- [@(0.0.255) void]_[* KillCaret]()&]
|
||||
[s2;b17;a17; Removes caret from Ctrl.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Upp`:`:Ctrl`:`:CancelPreedit`(`):%- [@(0.0.255) void]_[* CancelPreedit]()&]
|
||||
[s2; Terminates any input method composition in progress, if possible.
|
||||
Text input widgets typically call this on status change, like
|
||||
|
|
@ -2240,14 +2213,6 @@ l]_[*@3 ax]_`=_[@(0.0.255) true])&]
|
|||
[s7;i1120;a17; [*/ Return value]-|Value of ActiveX flag.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:Info`(const char`*`):%- [_^`:`:Ctrl^ Ctrl][@(0.0.255) `&]_[* Info]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 txt])&]
|
||||
[s2;b17;a17; Sets Tip text of Ctrl. This text is displayed as tooltip
|
||||
of Ctrl.&]
|
||||
[s7;i1120;a17; [%-*C@3 txt]-|Text.&]
|
||||
[s7;i1120;a17; [*/ Return value]-|`*this for method chaining.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:Ctrl`:`:HelpLine`(const char`*`):%- [_^`:`:Ctrl^ Ctrl][@(0.0.255) `&]_[* HelpLine]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 txt])&]
|
||||
[s2;b17;a17; Sets help topic link for Ctrl.&]
|
||||
|
|
|
|||
|
|
@ -260,6 +260,11 @@ while performing loop. If false, only TopWindow`'s relative windows
|
|||
[s7;%% [*/ Return value]-|Result true if Cancel otherwise false.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TopWindow`:`:GetExitCode`(`)const: [@(0.0.255) int]_[* GetExitCode]()_[@(0.0.255) c
|
||||
onst]&]
|
||||
[s2;%% Returns the result code of last Execute or Run methods.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TopWindow`:`:Minimize`(bool`): [@(0.0.255) void]_[* Minimize]([@(0.0.255) bool]_[*@3 eff
|
||||
ect]_`=_[@(0.0.255) false])&]
|
||||
[s2;%% Minimize window.&]
|
||||
|
|
|
|||
|
|
@ -1149,7 +1149,7 @@ ArrayCtrl::Column& ArrayCtrl::AddRowNumColumn(const char *text, int w) {
|
|||
int ArrayCtrl::FindColumnWithPos(int pos) const
|
||||
{
|
||||
for(int i = 0; i < column.GetCount(); i++) {
|
||||
const Mitor<int>& m = column[i].pos;
|
||||
const Vector<int>& m = column[i].pos;
|
||||
for(int j = 0; j < m.GetCount(); j++)
|
||||
if(Pos(m[j]) == pos) return i;
|
||||
}
|
||||
|
|
@ -1165,7 +1165,7 @@ Vector<int> ArrayCtrl::FindColumnsWithPos(int pos) const
|
|||
{
|
||||
Vector<int> r;
|
||||
for(int i = 0; i < column.GetCount(); i++) {
|
||||
const Mitor<int>& m = column[i].pos;
|
||||
const Vector<int>& m = column[i].pos;
|
||||
for(int j = 0; j < m.GetCount(); j++)
|
||||
if(Pos(m[j]) == pos)
|
||||
r.Add(i);
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
class Column : FormatConvert {
|
||||
ArrayCtrl *arrayctrl;
|
||||
int index;
|
||||
Mitor<int> pos;
|
||||
Vector<int> pos;
|
||||
const Convert *convert;
|
||||
Function<Value(const Value&)> convertby;
|
||||
Ptr<Ctrl> edit;
|
||||
|
|
|
|||
|
|
@ -339,32 +339,38 @@ const Button::Style *Button::St() const
|
|||
return st;
|
||||
}
|
||||
|
||||
void Button::Paint(Draw& w)
|
||||
void Button::PaintButton(Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus,
|
||||
const String& label, Font font, const Image& img,
|
||||
bool monoimg, int accesskey, bool visibleaccesskeys, bool disabled)
|
||||
{
|
||||
const Style *st = St();
|
||||
Size sz = GetSize();
|
||||
bool ds = !IsShowEnabled();
|
||||
DrawLabel dl;
|
||||
dl.text = label;
|
||||
dl.font = Nvl(font, st->font);
|
||||
dl.font = Nvl(font, st.font);
|
||||
dl.limg = img;
|
||||
dl.disabled = ds;
|
||||
dl.disabled = disabled;
|
||||
dl.lspc = !label.IsEmpty() && !img.IsEmpty() ? 4 : 0;
|
||||
if(*label == '\1')
|
||||
dl.align = ALIGN_LEFT;
|
||||
if(VisibleAccessKeys())
|
||||
if(visibleaccesskeys)
|
||||
dl.accesskey = accesskey;
|
||||
if(monoimg)
|
||||
dl.lcolor = SColorText;
|
||||
int i = GetVisualState();
|
||||
ChPaint(w, sz, st->look[i]);
|
||||
dl.ink = st->textcolor[i];
|
||||
ChPaint(w, r, st.look[visualstate]);
|
||||
dl.ink = st.textcolor[visualstate];
|
||||
if(monoimg)
|
||||
dl.lcolor = st->monocolor[i];
|
||||
dl.Paint(w, 3 + IsPush() * st->pressoffset.x, 3 + IsPush() * st->pressoffset.y,
|
||||
sz.cx - 6, sz.cy - 6);
|
||||
if(HasFocus())
|
||||
DrawFocus(w, Rect(sz).Deflated(st->focusmargin));
|
||||
dl.lcolor = st.monocolor[visualstate];
|
||||
bool push = visualstate == CTRL_PRESSED;
|
||||
dl.Paint(w, r.left + 3 + push * st.pressoffset.x, r.top + 3 + push * st.pressoffset.y,
|
||||
r.GetWidth() - 6, r.GetHeight() - 6);
|
||||
if(focus)
|
||||
DrawFocus(w, r.Deflated(st.focusmargin));
|
||||
}
|
||||
|
||||
void Button::Paint(Draw& w)
|
||||
{
|
||||
PaintButton(w, GetSize(), *St(), GetVisualState(), HasFocus(),
|
||||
label, font, img,
|
||||
monoimg, accesskey, VisibleAccessKeys(), !IsShowEnabled());
|
||||
}
|
||||
|
||||
void Button::MouseEnter(Point, dword)
|
||||
|
|
@ -498,6 +504,8 @@ void SpinButtons::FrameLayout(Rect& r)
|
|||
|
||||
void SpinButtons::FrameAddSize(Size& sz)
|
||||
{
|
||||
if(!visible)
|
||||
return;
|
||||
sz.cx += (1 + style->onsides) * (min(sz.cx / 2, style->width) - style->over);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ file
|
|||
PushCtrl.h,
|
||||
Button.cpp,
|
||||
Switch.cpp,
|
||||
VirtualButtons.cpp,
|
||||
EditCtrl.h,
|
||||
EditCtrl.hpp,
|
||||
EditField.cpp,
|
||||
TextEdit.h,
|
||||
Text.cpp,
|
||||
|
|
@ -34,6 +36,7 @@ file
|
|||
MultiButton.cpp,
|
||||
DropChoice.h,
|
||||
PopupTable.cpp,
|
||||
PopUpList.cpp,
|
||||
DropList.cpp,
|
||||
DropChoice.cpp,
|
||||
StaticCtrl.h,
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -222,6 +222,11 @@ int DocEdit::GetCursorPos(Point p) {
|
|||
return GetLength32();
|
||||
}
|
||||
|
||||
Rect DocEdit::GetCaret() const
|
||||
{
|
||||
return caret;
|
||||
}
|
||||
|
||||
void DocEdit::PlaceCaret(bool scroll) {
|
||||
Point cr = GetCaret((int)cursor);
|
||||
int fy = font.Info().GetLineHeight();
|
||||
|
|
@ -231,7 +236,7 @@ void DocEdit::PlaceCaret(bool scroll) {
|
|||
else
|
||||
sb.ScrollInto(cr.y, fy + 2);
|
||||
}
|
||||
SetCaret(cr.x + 1, cr.y - sb, 1, fy);
|
||||
caret = RectC(cr.x + 1, cr.y - sb, 1, fy);
|
||||
WhenSel();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ DropChoice::DropChoice() {
|
|||
always_drop = hide_drop = false;
|
||||
AddButton().Main() <<= THISBACK(Drop);
|
||||
NoDisplay();
|
||||
list.Normal();
|
||||
list.WhenSelect = [=] { Select(); };
|
||||
dropfocus = true;
|
||||
EnableDrop(false);
|
||||
|
|
@ -42,7 +41,11 @@ void DropChoice::Drop() {
|
|||
WhenDrop();
|
||||
if(dropfocus)
|
||||
owner->SetWantFocus();
|
||||
if(!list.FindSetCursor(owner->GetData()) && list.GetCount() > 0)
|
||||
int i = list.Find(owner->GetData());
|
||||
if(i >= 0)
|
||||
list.SetCursor(i);
|
||||
else
|
||||
if(list.GetCount() > 0)
|
||||
list.SetCursor(0);
|
||||
list.PopUp(owner,dropwidth);
|
||||
}
|
||||
|
|
@ -56,7 +59,7 @@ Value DropChoice::Get() const {
|
|||
if(!owner || owner->IsReadOnly() && !rodrop) return Value();
|
||||
int c = list.GetCursor();
|
||||
if(c < 0) return Value();
|
||||
return list.Get(c, 0);
|
||||
return list.Get(c);
|
||||
}
|
||||
|
||||
int DropChoice::GetIndex() const
|
||||
|
|
@ -172,7 +175,7 @@ void DropChoice::SerializeList(Stream& s) {
|
|||
}
|
||||
else
|
||||
for(int i = 0; i < n; i++) {
|
||||
v = list.Get(i, 0);
|
||||
v = list.Get(i);
|
||||
s % v;
|
||||
}
|
||||
EnableDrop(list.GetCount() || always_drop);
|
||||
|
|
@ -181,15 +184,15 @@ void DropChoice::SerializeList(Stream& s) {
|
|||
void DropChoice::AddHistory(const Value& v, int max) {
|
||||
if(IsNull(v)) return;
|
||||
for(int i = 0; i < list.GetCount(); i++)
|
||||
if(list.Get(i, 0) == v) {
|
||||
if(list.Get(i) == v) {
|
||||
list.Remove(i);
|
||||
break;
|
||||
}
|
||||
list.Insert(0, Vector<Value>() << v);
|
||||
list.Insert(0, v);
|
||||
if(list.GetCount() > max)
|
||||
list.SetCount(max);
|
||||
EnableDrop(list.GetCount() || always_drop);
|
||||
list.KillCursor();
|
||||
list.SetCursor(-1);
|
||||
}
|
||||
|
||||
DropChoice& DropChoice::AlwaysDrop(bool e)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
void DropEdge_Write(Value);
|
||||
|
||||
class PopUpTable : public ArrayCtrl {
|
||||
class PopUpTable : public ArrayCtrl { // deprecated, replaced with PopUpList
|
||||
public:
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual bool Key(dword key, int);
|
||||
|
|
@ -39,27 +39,115 @@ public:
|
|||
virtual ~PopUpTable();
|
||||
};
|
||||
|
||||
class PopUpList {
|
||||
protected:
|
||||
void PopupDeactivate();
|
||||
void PopupCancelMode();
|
||||
|
||||
struct PopupArrayCtrl : ArrayCtrl {
|
||||
PopUpList *list;
|
||||
|
||||
virtual void LeftUp(Point p, dword keyflags);
|
||||
virtual bool Key(dword key, int);
|
||||
};
|
||||
|
||||
struct Popup : Ctrl {
|
||||
PopUpList *list;
|
||||
PopupArrayCtrl ac;
|
||||
bool closing = false;
|
||||
|
||||
virtual void Deactivate() { if(!closing) list->PopupDeactivate(); }
|
||||
virtual void CancelMode() { if(!closing) list->PopupCancelMode(); }
|
||||
|
||||
Popup(PopUpList *list);
|
||||
};
|
||||
|
||||
Vector<Value> items;
|
||||
Vector<word> lineinfo;
|
||||
Vector<const Display *> linedisplay;
|
||||
One<Popup> popup;
|
||||
const ScrollBar::Style *sb_style = nullptr;
|
||||
const Display *display;
|
||||
const Convert *convert;
|
||||
int linecy;
|
||||
int cursor = -1;
|
||||
int16 droplines;
|
||||
int16 inpopup;
|
||||
|
||||
void DoSelect();
|
||||
void DoCancel();
|
||||
void DoClose();
|
||||
|
||||
void Reset();
|
||||
|
||||
friend class Popup;
|
||||
|
||||
public:
|
||||
Event<> WhenCancel;
|
||||
Event<> WhenSelect;
|
||||
|
||||
void PopUp(Ctrl *owner, int x, int top, int bottom, int width);
|
||||
void PopUp(Ctrl *owner, int width);
|
||||
void PopUp(Ctrl *owner);
|
||||
|
||||
void Clear();
|
||||
void SetCount(int n);
|
||||
void Add(const Value& v);
|
||||
void AddSeparator();
|
||||
void Remove(int i);
|
||||
void Insert(int i, const Value& v);
|
||||
|
||||
void SetCursor(int i);
|
||||
int GetCursor() const;
|
||||
|
||||
int GetCount() const { return items.GetCount(); }
|
||||
void Set(int i, const Value& v);
|
||||
Value Get(int i) const { return items[i]; }
|
||||
int Find(const Value& v) const;
|
||||
void SetScrollBarStyle(const ScrollBar::Style& s);
|
||||
void SetLineCy(int cy);
|
||||
int GetLineCy() const { return linecy; }
|
||||
void SetLineCy(int ii, int cy);
|
||||
int GetLineCy(int ii) const;
|
||||
bool Key(int c);
|
||||
bool IsLineEnabled(int ii) const;
|
||||
|
||||
void SetDisplay(const Display& d);
|
||||
const Display& GetDisplay() const { return *display; }
|
||||
|
||||
void SetDisplay(int i, const Display& d);
|
||||
const Display& GetDisplay(int i) const;
|
||||
|
||||
void SetConvert(const Convert& c);
|
||||
|
||||
PopUpList& SetDropLines(int _droplines) { droplines = _droplines; return *this; }
|
||||
|
||||
PopUpList();
|
||||
virtual ~PopUpList();
|
||||
};
|
||||
|
||||
class DropList : public MultiButton, public Convert {
|
||||
public:
|
||||
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
|
||||
virtual bool Key(dword key, int);
|
||||
virtual void SetData(const Value& data);
|
||||
virtual Value GetData() const;
|
||||
virtual void DropPush();
|
||||
|
||||
virtual Value Format(const Value& q) const;
|
||||
|
||||
private:
|
||||
PopUpTable list;
|
||||
PopUpList list;
|
||||
Index<Value> key;
|
||||
Value value;
|
||||
int dropwidth;
|
||||
const Convert *valueconvert;
|
||||
const Display *valuedisplay;
|
||||
bool displayall;
|
||||
bool dropfocus;
|
||||
bool notnull;
|
||||
bool alwaysdrop;
|
||||
bool usewheel;
|
||||
int16 dropwidth;
|
||||
bool displayall:1;
|
||||
bool dropfocus:1;
|
||||
bool notnull:1;
|
||||
bool alwaysdrop:1;
|
||||
bool usewheel:1;
|
||||
|
||||
void Select();
|
||||
void Cancel();
|
||||
|
|
@ -105,7 +193,7 @@ public:
|
|||
void Trim(int n);
|
||||
const Value& GetKey(int i) const { return key[i]; }
|
||||
|
||||
Value GetValue(int i) const { return list.Get(i, 0); }
|
||||
Value GetValue(int i) const { return list.Get(i); }
|
||||
Value GetValue() const;
|
||||
void SetValue(int i, const Value& v);
|
||||
void SetValue(const Value& v);
|
||||
|
|
@ -113,10 +201,10 @@ public:
|
|||
|
||||
void Adjust();
|
||||
void Adjust(const Value& k);
|
||||
|
||||
/*
|
||||
const PopUpTable& GetList() const { return list; }
|
||||
PopUpTable& ListObject() { return list; }
|
||||
|
||||
*/
|
||||
DropList& SetDropLines(int d) { list.SetDropLines(d); return *this; }
|
||||
DropList& SetValueConvert(const Convert& cv);
|
||||
DropList& SetConvert(const Convert& cv);
|
||||
|
|
@ -160,7 +248,7 @@ public:
|
|||
virtual void Serialize(Stream& s); //empty
|
||||
|
||||
protected:
|
||||
PopUpTable list;
|
||||
PopUpList list;
|
||||
Ctrl *owner;
|
||||
bool appending : 1;
|
||||
bool dropfocus : 1;
|
||||
|
|
@ -189,12 +277,12 @@ public:
|
|||
void Add(const Value& data);
|
||||
int Find(const Value& data) const { return list.Find(data); }
|
||||
void FindAdd(const Value& data);
|
||||
void Set(int i, const Value& data) { list.Set(i, 0, data); }
|
||||
void Set(int i, const Value& data) { list.Set(i, data); }
|
||||
void Remove(int i);
|
||||
void SerializeList(Stream& s);
|
||||
|
||||
int GetCount() const { return list.GetCount(); }
|
||||
Value Get(int i) const { return list.Get(i, 0); }
|
||||
Value Get(int i) const { return list.Get(i); }
|
||||
|
||||
void AddHistory(const Value& data, int max = 12);
|
||||
|
||||
|
|
@ -204,11 +292,11 @@ public:
|
|||
Value Get() const;
|
||||
int GetIndex() const;
|
||||
|
||||
DropChoice& SetDisplay(int i, const Display& d) { list.SetDisplay(i, 0, d); return *this; }
|
||||
DropChoice& SetDisplay(const Display& d) { list.ColumnAt(0).SetDisplay(d); return *this; }
|
||||
DropChoice& SetDisplay(int i, const Display& d) { list.SetDisplay(i, d); return *this; }
|
||||
DropChoice& SetDisplay(const Display& d) { list.SetDisplay(d); return *this; }
|
||||
DropChoice& SetLineCy(int lcy) { list.SetLineCy(lcy); return *this; }
|
||||
DropChoice& SetDisplay(const Display& d, int lcy) { SetDisplay(d); SetLineCy(lcy); return *this; }
|
||||
DropChoice& SetConvert(const Convert& d) { list.ColumnAt(0).SetConvert(d); return *this; }
|
||||
DropChoice& SetConvert(const Convert& d) { list.SetConvert(d); return *this; }
|
||||
DropChoice& SetDropLines(int n) { list.SetDropLines(n); return *this; }
|
||||
DropChoice& Appending() { appending = true; return *this; }
|
||||
DropChoice& AlwaysDrop(bool e = true);
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ void DropList::Sync() {
|
|||
if(displayall)
|
||||
v = value;
|
||||
int i = key.Find(value);
|
||||
const Display& d = valuedisplay ? *valuedisplay : i >= 0 ? list.GetDisplay(i, 0)
|
||||
: list.GetDisplay(0);
|
||||
if(i >= 0) v = list.Get(i, 0);
|
||||
const Display& d = valuedisplay ? *valuedisplay : i >= 0 ? list.GetDisplay(i)
|
||||
: list.GetDisplay();
|
||||
if(i >= 0) v = list.Get(i);
|
||||
MultiButton::SetDisplay(d);
|
||||
MultiButton::SetValueCy(list.GetLineCy());
|
||||
v = valueconvert->Format(v);
|
||||
|
|
@ -55,7 +55,7 @@ bool DropList::Key(dword k, int) {
|
|||
break;
|
||||
default:
|
||||
if(k >= 32 && k < K_CHAR_LIM) {
|
||||
bool b = list.Key(k, 1);
|
||||
bool b = list.Key(k);
|
||||
if(list.GetCursor() >= 0 && list.GetCursor() < key.GetCount() && key[list.GetCursor()] != value)
|
||||
Select();
|
||||
return b;
|
||||
|
|
@ -80,6 +80,11 @@ void DropList::Drop() {
|
|||
list.PopUp(this, dropwidth);
|
||||
}
|
||||
|
||||
void DropList::DropPush()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
void DropList::Select() {
|
||||
int c = list.GetCursor();
|
||||
if(c >= 0)
|
||||
|
|
@ -107,7 +112,6 @@ void DropList::ClearList() {
|
|||
key.Clear();
|
||||
list.Clear();
|
||||
Sync();
|
||||
list.Refresh();
|
||||
EnableDrop(false);
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +128,6 @@ DropList& DropList::Add(const Value& _key, const Value& text, bool enable)
|
|||
list.Add(text);
|
||||
if(!enable)
|
||||
list.SetLineCy(list.GetCount() - 1, 0);
|
||||
list.Refresh();
|
||||
EnableDrop();
|
||||
Sync();
|
||||
return *this;
|
||||
|
|
@ -143,7 +146,6 @@ DropList& DropList::AddSeparator()
|
|||
{
|
||||
key.Add(RawToValue(DummyValue__()));
|
||||
list.AddSeparator();
|
||||
list.Refresh();
|
||||
EnableDrop();
|
||||
Sync();
|
||||
return *this;
|
||||
|
|
@ -155,7 +157,6 @@ void DropList::Trim(int n) {
|
|||
key.Trim(n);
|
||||
list.SetCount(n);
|
||||
Sync();
|
||||
list.Refresh();
|
||||
EnableDrop(n);
|
||||
}
|
||||
|
||||
|
|
@ -177,7 +178,7 @@ Value DropList::GetValue() const {
|
|||
}
|
||||
|
||||
void DropList::SetValue(int i, const Value& v) {
|
||||
list.Set(i, 0, v);
|
||||
list.Set(i, v);
|
||||
EnableDrop();
|
||||
Sync();
|
||||
}
|
||||
|
|
@ -198,20 +199,20 @@ DropList& DropList::SetValueConvert(const Convert& cv)
|
|||
|
||||
DropList& DropList::SetConvert(const Convert& cv)
|
||||
{
|
||||
list.ColumnAt(0).SetConvert(cv);
|
||||
list.SetConvert(cv);
|
||||
return SetValueConvert(cv);
|
||||
}
|
||||
|
||||
DropList& DropList::SetDisplay(int i, const Display& d)
|
||||
{
|
||||
list.SetDisplay(i, 0, d);
|
||||
list.SetDisplay(i, d);
|
||||
Sync();
|
||||
return *this;
|
||||
}
|
||||
|
||||
DropList& DropList::SetDisplay(const Display& d)
|
||||
{
|
||||
list.ColumnAt(0).SetDisplay(d);
|
||||
list.SetDisplay(d);
|
||||
Sync();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -270,10 +271,9 @@ DropList::DropList()
|
|||
dropfocus = false;
|
||||
notnull = false;
|
||||
alwaysdrop = false;
|
||||
AddButton().Main().WhenPush = THISBACK(Drop);
|
||||
SetupDropPush();
|
||||
NoInitFocus();
|
||||
EnableDrop(false);
|
||||
list.Normal();
|
||||
list.WhenSelect = THISBACK(Select);
|
||||
list.WhenCancel = THISBACK(Cancel);
|
||||
dropwidth = 0;
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@ public:
|
|||
virtual void CancelMode();
|
||||
virtual String GetSelectionData(const String& fmt) const;
|
||||
virtual void State(int);
|
||||
virtual Rect GetCaret() const;
|
||||
|
||||
public:
|
||||
struct Style : ChStyle<Style> {
|
||||
|
|
@ -88,35 +89,43 @@ public:
|
|||
};
|
||||
|
||||
protected:
|
||||
const Style *style;
|
||||
enum {
|
||||
ATTR_TEXTCOLOR = Ctrl::ATTR_LAST,
|
||||
ATTR_INACTIVE_CONVERT,
|
||||
ATTR_CHARFILTER,
|
||||
ATTR_NULLICON,
|
||||
ATTR_NULLTEXT,
|
||||
ATTR_NULLINK,
|
||||
ATTR_NULLFONT,
|
||||
ATTR_LAST,
|
||||
};
|
||||
|
||||
ActiveEdgeFrame edge;
|
||||
|
||||
WString text;
|
||||
int sc;
|
||||
int cursor, anchor;
|
||||
|
||||
WString undotext;
|
||||
int undocursor, undoanchor;
|
||||
Rect16 dropcaret;
|
||||
|
||||
const Style *style;
|
||||
CharFilter filter;
|
||||
const Convert *convert;
|
||||
const Convert *inactive_convert;
|
||||
Font font;
|
||||
Color textcolor;
|
||||
|
||||
WString nulltext;
|
||||
Color nullink;
|
||||
Font nullfont;
|
||||
Image nullicon;
|
||||
Font font;
|
||||
|
||||
int sc;
|
||||
int cursor, anchor;
|
||||
|
||||
int undocursor, undoanchor;
|
||||
|
||||
int maxlen;
|
||||
int autosize;
|
||||
byte charset;
|
||||
int fsell, fselh; // used to hold selection after LostFocus for X11 middle mouse copy
|
||||
|
||||
int dropcursor;
|
||||
Rect dropcaret;
|
||||
bool selclick;
|
||||
int dropcursor;
|
||||
|
||||
byte charset;
|
||||
|
||||
bool selclick:1;
|
||||
|
||||
bool password:1;
|
||||
bool autoformat:1;
|
||||
|
|
@ -140,7 +149,6 @@ protected:
|
|||
int GetStringCx(const wchar *text, int n);
|
||||
int GetCaret(int cursor) const;
|
||||
int GetCursor(int posx);
|
||||
void SyncCaret();
|
||||
void Finish(bool refresh = true);
|
||||
void SaveUndo();
|
||||
void DoAutoFormat();
|
||||
|
|
@ -154,6 +162,13 @@ protected:
|
|||
virtual void HighlightText(Vector<Highlight>& hl);
|
||||
virtual int64 GetTotal() const { return text.GetLength(); }
|
||||
virtual int GetCharAt(int64 pos) const { return text[(int)pos]; }
|
||||
|
||||
// Spin support
|
||||
virtual void PaintSpace(Draw& w);
|
||||
virtual int GetSpaceLeft() const;
|
||||
virtual int GetSpaceRight() const;
|
||||
virtual void EditCapture();
|
||||
virtual bool HasEditCapture();
|
||||
|
||||
public:
|
||||
Event<Bar&> WhenBar;
|
||||
|
|
@ -216,7 +231,7 @@ public:
|
|||
bool IsPassword() const { return password; }
|
||||
EditField& SetFilter(int (*f)(int)) { filter = f; return *this; }
|
||||
EditField& SetConvert(const Convert& c) { convert = &c; Refresh(); return *this; }
|
||||
EditField& SetInactiveConvert(const Convert& c) { inactive_convert = &c; Refresh(); return *this; }
|
||||
EditField& SetInactiveConvert(const Convert& c) { SetVoidPtrAttr(ATTR_INACTIVE_CONVERT, &c); Refresh(); return *this; }
|
||||
EditField& AutoFormat(bool b = true) { autoformat = b; return *this; }
|
||||
EditField& NoAutoFormat() { return AutoFormat(false); }
|
||||
bool IsAutoFormat() const { return autoformat; }
|
||||
|
|
@ -227,9 +242,9 @@ public:
|
|||
bool IsClickSelect() const { return clickselect; }
|
||||
EditField& InitCaps(bool b = true) { initcaps = b; return *this; }
|
||||
bool IsInitCaps() const { return initcaps; }
|
||||
EditField& NullText(const Image& icon, const char *text = t_("(default)"), Color ink = SColorDisabled);
|
||||
EditField& NullText(const Image& icon, const char *text = t_("(default)"), Color ink = Null);
|
||||
EditField& NullText(const Image& icon, const char *text, Font fnt, Color ink);
|
||||
EditField& NullText(const char *text = t_("(default)"), Color ink = SColorDisabled);
|
||||
EditField& NullText(const char *text = t_("(default)"), Color ink = Null);
|
||||
EditField& NullText(const char *text, Font fnt, Color ink);
|
||||
EditField& MaxChars(int mc) { maxlen = mc; return *this; }
|
||||
int GetMaxChars() const { return maxlen; }
|
||||
|
|
@ -369,10 +384,24 @@ void WithSpin_Add(double& value, double inc, double min, bool roundfrommin) {
|
|||
}
|
||||
|
||||
template <class DataType, class Base, class IncType = DataType>
|
||||
class WithSpin : public Base {
|
||||
class WithSpin : public Base, private VirtualButtons {
|
||||
public:
|
||||
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
|
||||
virtual bool Key(dword key, int repcnt);
|
||||
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);
|
||||
|
||||
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;
|
||||
virtual const Button::Style& ButtonStyle(int i) const;
|
||||
virtual void ButtonPush(int i);
|
||||
virtual void ButtonRepeat(int i);
|
||||
|
||||
protected:
|
||||
void Inc();
|
||||
|
|
@ -380,9 +409,10 @@ protected:
|
|||
void Init();
|
||||
|
||||
private:
|
||||
SpinButtons sb;
|
||||
const SpinButtons::Style *style;
|
||||
IncType inc;
|
||||
bool roundfrommin;
|
||||
bool roundfrommin = false;
|
||||
bool visible = true;
|
||||
bool mousewheel = true;
|
||||
bool keys = true;
|
||||
|
||||
|
|
@ -391,12 +421,14 @@ public:
|
|||
|
||||
WithSpin& SetInc(IncType _inc = 1) { inc = _inc; return *this; }
|
||||
DataType GetInc() const { return inc; }
|
||||
|
||||
WithSpin& OnSides(bool b = true) { sb.OnSides(b); return *this; }
|
||||
bool IsOnSides() const { return sb.IsOnSides(); }
|
||||
|
||||
WithSpin& ShowSpin(bool s = true) { sb.Show(s); return *this; }
|
||||
bool IsSpinVisible() const { return sb.IsVisible(); }
|
||||
WithSpin& SetStyle(SpinButtons::Style& s) { style = &s; return *this; }
|
||||
|
||||
WithSpin& OnSides(bool b = true);
|
||||
bool IsOnSides() const { return style->onsides; }
|
||||
|
||||
WithSpin& ShowSpin(bool b = true) { visible = b; Base::RefreshLayout(); return *this; }
|
||||
bool IsSpinVisible() const { return visible; }
|
||||
|
||||
WithSpin& RoundFromMin(bool b = true) { roundfrommin = b; return *this; }
|
||||
|
||||
|
|
@ -406,122 +438,13 @@ public:
|
|||
WithSpin& KeySpin(bool b = true) { keys = b; return *this; }
|
||||
WithSpin& NoKeySpin() { return KeySpin(false); }
|
||||
|
||||
SpinButtons& SpinButtonsObject() { return sb; }
|
||||
const SpinButtons& SpinButtonsObject() const { return sb; }
|
||||
|
||||
WithSpin();
|
||||
WithSpin(IncType inc); // deprecated
|
||||
WithSpin(DataType min, DataType max, IncType inc); // deprecated
|
||||
virtual ~WithSpin() {}
|
||||
};
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin()
|
||||
: inc(WithSpin_DefaultIncValue<IncType>())
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin(IncType inc)
|
||||
: inc(inc)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin(DataType min, DataType max, IncType inc)
|
||||
: inc(WithSpin_DefaultIncValue<IncType>())
|
||||
{
|
||||
Base::MinMax(min, max);
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Init()
|
||||
{
|
||||
Ctrl::AddFrame(sb);
|
||||
sb.inc.WhenRepeat = sb.inc.WhenAction = THISBACK(Inc);
|
||||
sb.dec.WhenRepeat = sb.dec.WhenAction = THISBACK(Dec);
|
||||
roundfrommin = false;
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Inc()
|
||||
{
|
||||
if(Ctrl::IsReadOnly()) {
|
||||
BeepExclamation();
|
||||
return;
|
||||
}
|
||||
DataType d = Base::GetData();
|
||||
if(!IsNull(d)) {
|
||||
WithSpin_Add(d, inc, Base::GetMin(), roundfrommin);
|
||||
if(IsNull(Base::GetMax()) || d <= Base::GetMax()) {
|
||||
Base::SetData(d);
|
||||
Ctrl::Action();
|
||||
}
|
||||
}
|
||||
else {
|
||||
DataType min = Base::GetMin();
|
||||
if(IsNull(min) || min <= Base::GetDefaultMin())
|
||||
Base::SetData(WithSpin_DefaultStartValue<DataType>());
|
||||
else
|
||||
Base::SetData(min);
|
||||
}
|
||||
Ctrl::SetFocus();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Dec()
|
||||
{
|
||||
if(Ctrl::IsReadOnly()) {
|
||||
BeepExclamation();
|
||||
return;
|
||||
}
|
||||
DataType d = Base::GetData();
|
||||
if(!IsNull(d)) {
|
||||
WithSpin_Add(d, -inc, Base::GetMin(), roundfrommin);
|
||||
if(IsNull(Base::GetMin()) || d >= Base::GetMin()) {
|
||||
Base::SetData(d);
|
||||
Ctrl::Action();
|
||||
}
|
||||
}
|
||||
else {
|
||||
DataType max = Base::GetMax();
|
||||
if(IsNull(max) || max >= Base::GetDefaultMax())
|
||||
Base::SetData(WithSpin_DefaultStartValue<DataType>());
|
||||
else
|
||||
Base::SetData(max);
|
||||
}
|
||||
Ctrl::SetFocus();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
bool WithSpin<DataType, Base, IncType>::Key(dword key, int repcnt)
|
||||
{
|
||||
if(keys) {
|
||||
if(key == K_UP) {
|
||||
Inc();
|
||||
return true;
|
||||
}
|
||||
if(key == K_DOWN) {
|
||||
Dec();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Base::Key(key, repcnt);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::MouseWheel(Point, int zdelta, dword)
|
||||
{
|
||||
if(mousewheel) {
|
||||
if(zdelta < 0)
|
||||
Dec();
|
||||
else
|
||||
Inc();
|
||||
}
|
||||
}
|
||||
#include "EditCtrl.hpp"
|
||||
|
||||
typedef WithSpin<int, EditInt> EditIntSpin;
|
||||
typedef WithSpin<int64, EditInt64> EditInt64Spin;
|
||||
|
|
|
|||
201
uppsrc/CtrlLib/EditCtrl.hpp
Normal file
201
uppsrc/CtrlLib/EditCtrl.hpp
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin()
|
||||
: inc(WithSpin_DefaultIncValue<IncType>())
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin(IncType inc)
|
||||
: inc(inc)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>::WithSpin(DataType min, DataType max, IncType inc)
|
||||
: inc(WithSpin_DefaultIncValue<IncType>())
|
||||
{
|
||||
Base::MinMax(min, max);
|
||||
Init();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Init()
|
||||
{
|
||||
style = &SpinButtons::StyleDefault();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
WithSpin<DataType, Base, IncType>& WithSpin<DataType, Base, IncType>::OnSides(bool b)
|
||||
{
|
||||
SetStyle(b ? SpinButtons::StyleOnSides() : SpinButtons::StyleDefault());
|
||||
Base::RefreshLayout();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Inc()
|
||||
{
|
||||
if(Ctrl::IsReadOnly()) {
|
||||
BeepExclamation();
|
||||
return;
|
||||
}
|
||||
DataType d = Base::GetData();
|
||||
if(!IsNull(d)) {
|
||||
WithSpin_Add(d, inc, Base::GetMin(), roundfrommin);
|
||||
if(IsNull(Base::GetMax()) || d <= Base::GetMax()) {
|
||||
Base::SetData(d);
|
||||
Ctrl::Action();
|
||||
}
|
||||
}
|
||||
else {
|
||||
DataType min = Base::GetMin();
|
||||
if(IsNull(min) || min <= Base::GetDefaultMin())
|
||||
Base::SetData(WithSpin_DefaultStartValue<DataType>());
|
||||
else
|
||||
Base::SetData(min);
|
||||
}
|
||||
Ctrl::SetFocus();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::Dec()
|
||||
{
|
||||
if(Ctrl::IsReadOnly()) {
|
||||
BeepExclamation();
|
||||
return;
|
||||
}
|
||||
DataType d = Base::GetData();
|
||||
if(!IsNull(d)) {
|
||||
WithSpin_Add(d, -inc, Base::GetMin(), roundfrommin);
|
||||
if(IsNull(Base::GetMin()) || d >= Base::GetMin()) {
|
||||
Base::SetData(d);
|
||||
Ctrl::Action();
|
||||
}
|
||||
}
|
||||
else {
|
||||
DataType max = Base::GetMax();
|
||||
if(IsNull(max) || max >= Base::GetDefaultMax())
|
||||
Base::SetData(WithSpin_DefaultStartValue<DataType>());
|
||||
else
|
||||
Base::SetData(max);
|
||||
}
|
||||
Ctrl::SetFocus();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
bool WithSpin<DataType, Base, IncType>::Key(dword key, int repcnt)
|
||||
{
|
||||
if(keys) {
|
||||
if(key == K_UP) {
|
||||
Inc();
|
||||
return true;
|
||||
}
|
||||
if(key == K_DOWN) {
|
||||
Dec();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Base::Key(key, repcnt);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
Image WithSpin<DataType, Base, IncType>::MouseEvent(int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
if(ButtonsMouseEvent(this, event, p))
|
||||
return Image::Arrow();
|
||||
return Base::MouseEvent(event, p, zdelta, keyflags);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::MouseWheel(Point, int zdelta, dword)
|
||||
{
|
||||
if(mousewheel) {
|
||||
if(zdelta < 0)
|
||||
Dec();
|
||||
else
|
||||
Inc();
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if(!visible)
|
||||
return 0;
|
||||
return style->onsides ? min(Base::GetSize().cx / 2, style->width) - style->over : 0;
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
int WithSpin<DataType, Base, IncType>::GetSpaceRight() const
|
||||
{
|
||||
if(!visible)
|
||||
return 0;
|
||||
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)
|
||||
{
|
||||
if(i)
|
||||
Inc();
|
||||
else
|
||||
Dec();
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::ButtonRepeat(int i)
|
||||
{
|
||||
ButtonPush(i);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
void WithSpin<DataType, Base, IncType>::PaintSpace(Draw& w)
|
||||
{
|
||||
PaintButtons(w, this);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
int WithSpin<DataType, Base, IncType>::ButtonCount() const
|
||||
{
|
||||
return visible ? 2 : 0;
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
Rect WithSpin<DataType, Base, IncType>::ButtonRect(int i) const
|
||||
{
|
||||
Rect rect = Base::GetSize();
|
||||
int h = rect.GetHeight();
|
||||
int h7 = min(rect.GetWidth() / 2, style->width);
|
||||
int h7o = h7 - style->over;
|
||||
if(style->onsides)
|
||||
return i ? RectC(rect.left - style->over, rect.top, h7, h) : RectC(rect.right - h7o, rect.top, h7, h);
|
||||
int h2 = h / 2;
|
||||
return i ? RectC(rect.right - h7o, rect.top, h7, h2) : RectC(rect.right - h7o, rect.top + h2, h7, h - h2);
|
||||
}
|
||||
|
||||
template <class DataType, class Base, class IncType>
|
||||
const Button::Style& WithSpin<DataType, Base, IncType>::ButtonStyle(int i) const
|
||||
{
|
||||
return i ? style->inc : style->dec;
|
||||
}
|
||||
|
|
@ -180,12 +180,37 @@ int EditField::GetStdHeight(Font font)
|
|||
|
||||
Size EditField::GetMinSize() const
|
||||
{
|
||||
return AddFrameSize(10, font.GetCy() + (no_internal_margin ? 0 : 4));
|
||||
return AddFrameSize(10 + GetSpaceLeft() + GetSpaceRight(), font.GetCy() + (no_internal_margin ? 0 : 4));
|
||||
}
|
||||
|
||||
void EditField::PaintSpace(Draw& w)
|
||||
{
|
||||
}
|
||||
|
||||
int EditField::GetSpaceLeft() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EditField::GetSpaceRight() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void EditField::EditCapture()
|
||||
{
|
||||
}
|
||||
|
||||
bool EditField::HasEditCapture()
|
||||
{
|
||||
return HasCapture();
|
||||
}
|
||||
|
||||
int EditField::GetCursor(int posx)
|
||||
{
|
||||
posx -= 2;
|
||||
posx -= GetSpaceLeft();
|
||||
if(!no_internal_margin)
|
||||
posx -= 2;
|
||||
if(posx <= 0) return 0;
|
||||
|
||||
int count = text.GetLength();
|
||||
|
|
@ -281,30 +306,37 @@ Color EditField::GetPaper()
|
|||
|
||||
void EditField::Paint(Draw& w)
|
||||
{
|
||||
int lspace = GetSpaceLeft();
|
||||
int rspace = GetSpaceRight();
|
||||
Size sz = GetSize();
|
||||
bool enabled = IsShowEnabled();
|
||||
Color paper = GetPaper();
|
||||
Color textcolor = GetColorAttr(ATTR_TEXTCOLOR);
|
||||
Color ink = enabled ? Nvl(textcolor, style->text) : style->textdisabled;
|
||||
int fcy = font.GetCy();
|
||||
int yy = GetTy();
|
||||
w.DrawRect(sz, paper);
|
||||
PaintSpace(w);
|
||||
if(!no_internal_margin) {
|
||||
w.DrawRect(0, 0, 2, sz.cy, paper);
|
||||
w.DrawRect(0, 0, sz.cx, yy, paper);
|
||||
w.DrawRect(0, yy + fcy, sz.cx, sz.cy - yy - fcy, paper);
|
||||
w.DrawRect(sz.cx - 2, 0, 2, sz.cy, paper);
|
||||
w.Clipoff(2, yy, sz.cx - 4, fcy);
|
||||
lspace += 2;
|
||||
rspace += 2;
|
||||
}
|
||||
if(lspace || rspace)
|
||||
w.Clipoff(lspace, no_internal_margin ? 0 : yy, sz.cx - lspace - rspace, no_internal_margin ? 0 : fcy);
|
||||
int x = -sc;
|
||||
w.DrawRect(0, 0, sz.cx, fcy, paper);
|
||||
String nulltext = GetTextAttr(ATTR_NULLTEXT);
|
||||
Image nullicon = GetAttr<Image>(ATTR_NULLICON);
|
||||
if(IsNull(text) && (!IsNull(nulltext) || !IsNull(nullicon))) {
|
||||
const wchar *txt = nulltext;
|
||||
WString nt = nulltext.ToWString();
|
||||
const wchar *txt = nt;
|
||||
if(!IsNull(nullicon)) {
|
||||
int icx = nullicon.GetWidth();
|
||||
w.DrawRect(x, 0, icx + 4, fcy, paper);
|
||||
w.DrawImage(x, (fcy - nullicon.GetHeight()) / 2, nullicon);
|
||||
x += icx + 4;
|
||||
}
|
||||
Paints(w, x, fcy, txt, nullink, paper, nulltext.GetLength(), false, nullfont, Null, false);
|
||||
Paints(w, x, fcy, txt, Nvl(GetColorAttr(ATTR_NULLINK), SColorDisabled()),
|
||||
paper, nt.GetLength(), false, Nvl(GetFontAttr(ATTR_NULLFONT), StdFont().Italic()), Null, false);
|
||||
}
|
||||
else {
|
||||
const wchar *txt = text;
|
||||
|
|
@ -333,9 +365,9 @@ void EditField::Paint(Draw& w)
|
|||
b = i;
|
||||
}
|
||||
}
|
||||
if(!no_internal_margin)
|
||||
w.End();
|
||||
DrawTiles(w, dropcaret, CtrlImg::checkers());
|
||||
if(lspace || rspace)
|
||||
w.End();
|
||||
}
|
||||
|
||||
bool EditField::GetSelection(int& l, int& h) const
|
||||
|
|
@ -362,15 +394,14 @@ bool EditField::IsSelection() const
|
|||
|
||||
Rect EditField::GetCaretRect(int pos) const
|
||||
{
|
||||
return RectC(GetCaret(pos) - sc + 2 * !no_internal_margin
|
||||
return RectC(GetCaret(pos) - sc + 2 * !no_internal_margin + GetSpaceLeft()
|
||||
- font.GetRightSpace('o') + font.GetLeftSpace('o'), GetTy(),
|
||||
DPI(1), min(GetSize().cy - 2 * GetTy(), font.GetCy()));
|
||||
}
|
||||
|
||||
void EditField::SyncCaret()
|
||||
Rect EditField::GetCaret() const
|
||||
{
|
||||
Rect r = GetCaretRect(cursor);
|
||||
SetCaret(r.left, r.top, r.GetWidth(), r.GetHeight());
|
||||
return GetCaretRect(cursor);
|
||||
}
|
||||
|
||||
void EditField::Finish(bool refresh)
|
||||
|
|
@ -391,7 +422,9 @@ void EditField::Finish(bool refresh)
|
|||
LeftPos(r.left, sz.cx);
|
||||
sz = GetSize();
|
||||
}
|
||||
sz.cx -= 2;
|
||||
if(!no_internal_margin)
|
||||
sz.cx -= 2;
|
||||
sz.cx -= GetSpaceLeft() + GetSpaceRight();
|
||||
if(sz.cx <= 0) return;
|
||||
int x = GetCaret(cursor);
|
||||
int rspc = max(font.GetRightSpace('o'), font.GetCy() / 5); // sometimes RightSpace is not implemented (0)
|
||||
|
|
@ -411,7 +444,6 @@ void EditField::Finish(bool refresh)
|
|||
}
|
||||
if(refresh)
|
||||
RefreshAll();
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
void EditField::Layout()
|
||||
|
|
@ -432,6 +464,7 @@ void EditField::SelSource()
|
|||
|
||||
void EditField::GotFocus()
|
||||
{
|
||||
auto inactive_convert = (const Convert *)GetVoidPtrAttr(ATTR_INACTIVE_CONVERT);
|
||||
if(autoformat && IsEditable() && !IsNull(text) && inactive_convert) {
|
||||
Value v = convert->Scan(text);
|
||||
if(!v.IsError()) {
|
||||
|
|
@ -453,6 +486,7 @@ void EditField::LostFocus()
|
|||
if(autoformat && IsEditable() && !IsNull(text) && !IsDragAndDropSource()) {
|
||||
Value v = convert->Scan(text);
|
||||
if(!v.IsError()) {
|
||||
auto inactive_convert = (const Convert *)GetVoidPtrAttr(ATTR_INACTIVE_CONVERT);
|
||||
const Convert * cv = inactive_convert ? inactive_convert : convert;
|
||||
WString s = cv->Format(v);
|
||||
if(s != text) text = s;
|
||||
|
|
@ -487,6 +521,7 @@ void EditField::LeftDown(Point p, dword flags)
|
|||
return;
|
||||
}
|
||||
SetCapture();
|
||||
EditCapture();
|
||||
Move(c, flags & K_SHIFT);
|
||||
Finish();
|
||||
}
|
||||
|
|
@ -509,7 +544,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;
|
||||
|
|
@ -531,7 +566,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();
|
||||
}
|
||||
|
|
@ -645,10 +680,8 @@ void EditField::Remove(int pos, int n)
|
|||
{
|
||||
if(IsReadOnly()) return;
|
||||
text.Remove(pos, n);
|
||||
if(cursor >= text.GetLength()) {
|
||||
if(cursor >= text.GetLength())
|
||||
cursor = text.GetLength();
|
||||
SyncCaret();
|
||||
}
|
||||
Update();
|
||||
}
|
||||
|
||||
|
|
@ -706,7 +739,7 @@ void EditField::DragAndDrop(Point p, PasteClip& d)
|
|||
dc = RectC(x - sc + 2 - font.GetRightSpace('o'), GetTy(),
|
||||
1, min(GetSize().cy - 2 * GetTy(), font.GetCy()));
|
||||
}
|
||||
if(dc != dropcaret) {
|
||||
if((Rect16)dc != dropcaret) {
|
||||
Refresh(dropcaret);
|
||||
dropcaret = dc;
|
||||
Refresh(dropcaret);
|
||||
|
|
@ -728,7 +761,6 @@ void EditField::DragRepeat(Point p)
|
|||
if(a != sc) {
|
||||
sc = a;
|
||||
Refresh();
|
||||
SyncCaret();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -745,7 +777,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);
|
||||
|
|
@ -981,6 +1013,7 @@ void EditField::SetText(const WString& txt)
|
|||
|
||||
void EditField::SetData(const Value& data)
|
||||
{
|
||||
auto inactive_convert = (const Convert *)GetVoidPtrAttr(ATTR_INACTIVE_CONVERT);
|
||||
const Convert * cv = convert;
|
||||
if(!HasFocus() && inactive_convert)
|
||||
cv = inactive_convert;
|
||||
|
|
@ -1010,7 +1043,6 @@ void EditField::Reset()
|
|||
clickselect = false;
|
||||
filter = CharFilterUnicode;
|
||||
convert = &NoConvert();
|
||||
inactive_convert = NULL;
|
||||
initcaps = false;
|
||||
maxlen = INT_MAX;
|
||||
autosize = false;
|
||||
|
|
@ -1021,10 +1053,10 @@ void EditField::Reset()
|
|||
SetStyle(StyleDefault());
|
||||
SetFrame(edge);
|
||||
font = StdFont();
|
||||
textcolor = Null;
|
||||
showspaces = false;
|
||||
no_internal_margin = false;
|
||||
fsell = fselh = -1;
|
||||
DeleteAttr<Image>(ATTR_NULLICON);
|
||||
}
|
||||
|
||||
EditField& EditField::SetFont(Font _font)
|
||||
|
|
@ -1036,25 +1068,27 @@ EditField& EditField::SetFont(Font _font)
|
|||
|
||||
EditField& EditField::SetColor(Color c)
|
||||
{
|
||||
textcolor = c;
|
||||
SetColorAttr(ATTR_TEXTCOLOR, c);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
EditField& EditField::NullText(const Image& icon, const char *text, Font fnt, Color ink)
|
||||
{
|
||||
nullicon = icon;
|
||||
nulltext = text;
|
||||
nulltext << " ";
|
||||
nullink = ink;
|
||||
nullfont = fnt;
|
||||
if(!IsNull(icon))
|
||||
CreateAttr<Image>(ATTR_NULLICON) = icon;
|
||||
String h = text;
|
||||
h << " ";
|
||||
SetTextAttr(ATTR_NULLTEXT, h);
|
||||
SetColorAttr(ATTR_NULLINK, ink);
|
||||
SetFontAttr(ATTR_NULLFONT, fnt);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
EditField& EditField::NullText(const Image& icon, const char *text, Color ink)
|
||||
{
|
||||
return NullText(icon, text, GetFont().Italic(), ink);
|
||||
return NullText(icon, text, Null, ink);
|
||||
}
|
||||
|
||||
EditField& EditField::NullText(const char *text, Font fnt, Color ink)
|
||||
|
|
@ -1064,7 +1098,7 @@ EditField& EditField::NullText(const char *text, Font fnt, Color ink)
|
|||
|
||||
EditField& EditField::NullText(const char *text, Color ink)
|
||||
{
|
||||
return NullText(text, GetFont().Italic(), ink);
|
||||
return NullText(text, Null, ink);
|
||||
}
|
||||
|
||||
EditField::EditField()
|
||||
|
|
@ -1075,6 +1109,9 @@ EditField::EditField()
|
|||
WhenBar = THISBACK(StdBar);
|
||||
}
|
||||
|
||||
EditField::~EditField() {}
|
||||
EditField::~EditField()
|
||||
{
|
||||
DeleteAttr<Image>(ATTR_NULLICON);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -743,6 +743,8 @@ void HeaderCtrl::Serialize(Stream& s) {
|
|||
if(version >= 0x04) {
|
||||
int n = col.GetCount();
|
||||
s / n;
|
||||
if(n < 0 || n > 10000)
|
||||
s.LoadError();
|
||||
Array<Column> col2 = clone(col);
|
||||
if(s.IsLoading())
|
||||
col2.InsertN(0, n);
|
||||
|
|
@ -757,10 +759,10 @@ void HeaderCtrl::Serialize(Stream& s) {
|
|||
}
|
||||
col2[i].index = ndx;
|
||||
s % col2[i].ratio;
|
||||
s % col2[i].visible;
|
||||
s % col2[i].visible;
|
||||
}
|
||||
if(s.IsLoading() && n == col.GetCount()) {
|
||||
col2.Trim(n);
|
||||
col2.SetCount(n);
|
||||
col = pick(col2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,14 +29,14 @@ public:
|
|||
protected:
|
||||
virtual void LabelUpdate();
|
||||
|
||||
String tip;
|
||||
HeaderCtrl *header;
|
||||
double ratio;
|
||||
bool visible;
|
||||
int min, max;
|
||||
int margin;
|
||||
Color paper;
|
||||
int index;
|
||||
String tip;
|
||||
bool visible;
|
||||
|
||||
void Paint(bool& first, Draw& w,
|
||||
int x, int y, int cx, int cy, bool disabled, bool push, bool hl);
|
||||
|
|
|
|||
|
|
@ -115,20 +115,6 @@ int ChooseAccessKey(const char *text, dword used)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DrawLabel::DrawLabel()
|
||||
{
|
||||
push = focus = disabled = false;
|
||||
lspc = rspc = 0;
|
||||
limg_never_hide = false;
|
||||
rimg_never_hide = false;
|
||||
ink = disabledink = Null;
|
||||
align = valign = ALIGN_CENTER;
|
||||
accesskey = 0;
|
||||
accesspos = -1;
|
||||
font = StdFont();
|
||||
nowrap = false;
|
||||
}
|
||||
|
||||
Size DrawLabel::GetSize(int txtcx) const
|
||||
{
|
||||
return GetSize(txtcx, limg.GetSize(), lspc, rimg.GetSize(), rspc);
|
||||
|
|
@ -289,7 +275,17 @@ Size DrawLabel::Paint(Draw& w, int x, int y, int cx, int cy, bool vak) const
|
|||
|
||||
void LabelBase::LabelUpdate() {}
|
||||
|
||||
DrawLabel LabelBase::Make() const
|
||||
{
|
||||
DrawLabel lx;
|
||||
(DrawLabelBasic&)lx = lbl;
|
||||
if(ext)
|
||||
(DrawLabelExt&)lx = *ext;
|
||||
return lx;
|
||||
}
|
||||
|
||||
LabelBase& LabelBase::SetLeftImage(const Image& img, int spc, bool never_hide) {
|
||||
DrawLabelExt& lbl = Ext();
|
||||
lbl.limg = img;
|
||||
lbl.lspc = spc;
|
||||
lbl.limg_never_hide = never_hide;
|
||||
|
|
@ -298,6 +294,7 @@ LabelBase& LabelBase::SetLeftImage(const Image& img, int spc, bool never_hide) {
|
|||
}
|
||||
|
||||
LabelBase& LabelBase::SetRightImage(const Image& img, int spc, bool never_hide) {
|
||||
DrawLabelExt& lbl = Ext();
|
||||
lbl.rimg = img;
|
||||
lbl.rspc = spc;
|
||||
lbl.rimg_never_hide = never_hide;
|
||||
|
|
@ -306,7 +303,7 @@ LabelBase& LabelBase::SetRightImage(const Image& img, int spc, bool never_hide)
|
|||
}
|
||||
|
||||
LabelBase& LabelBase::SetPaintRect(const PaintRect& paintrect) {
|
||||
lbl.paintrect = paintrect;
|
||||
Ext().paintrect = paintrect;
|
||||
LabelUpdate();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -362,7 +359,7 @@ LabelBase& LabelBase::SetVAlign(int valign) {
|
|||
|
||||
Size LabelBase::PaintLabel(Ctrl *ctrl, Draw& w, const Rect& r, bool disabled, bool push, bool focus, bool vak)
|
||||
{
|
||||
DrawLabel lbl1 = lbl;
|
||||
DrawLabel lbl1 = Make();
|
||||
lbl1.disabled = disabled;
|
||||
lbl1.push = push;
|
||||
lbl1.focus = focus;
|
||||
|
|
@ -387,12 +384,13 @@ Size LabelBase::PaintLabel(Draw& w, int x, int y, int cx, int cy, bool disabled,
|
|||
|
||||
Size LabelBase::GetLabelSize() const
|
||||
{
|
||||
return lbl.GetSize();
|
||||
return Make().GetSize();
|
||||
}
|
||||
|
||||
void LinkToolTipIn__();
|
||||
|
||||
LabelBase::~LabelBase() {
|
||||
LabelBase::~LabelBase()
|
||||
{
|
||||
LinkToolTipIn__();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,30 +28,41 @@ void DrawVertDrop(Draw& w, int x, int y, int cy);
|
|||
Point GetDragScroll(Ctrl *ctrl, Point p, Size max);
|
||||
Point GetDragScroll(Ctrl *ctrl, Point p, int max = 16);
|
||||
|
||||
struct DrawLabel {
|
||||
bool push;
|
||||
bool focus;
|
||||
bool disabled;
|
||||
bool limg_never_hide;
|
||||
bool rimg_never_hide;
|
||||
|
||||
PaintRect paintrect;
|
||||
Image limg;
|
||||
Color lcolor;
|
||||
int lspc;
|
||||
struct DrawLabelBasic {
|
||||
String text;
|
||||
Font font;
|
||||
Color ink, disabledink;
|
||||
Image rimg;
|
||||
Color rcolor;
|
||||
int rspc;
|
||||
|
||||
int align, valign;
|
||||
|
||||
bool nowrap;
|
||||
Color ink;
|
||||
Color disabledink;
|
||||
|
||||
int accesskey;
|
||||
int accesspos;
|
||||
|
||||
int align:4;
|
||||
int valign:4;
|
||||
|
||||
bool nowrap:1;
|
||||
|
||||
DrawLabelBasic() { align = valign = ALIGN_CENTER; nowrap = false; accesskey = 0; font = StdFont(); }
|
||||
};
|
||||
|
||||
struct DrawLabelExt {
|
||||
PaintRect paintrect;
|
||||
|
||||
Image limg;
|
||||
Image rimg;
|
||||
|
||||
Color lcolor;
|
||||
int lspc = 0;
|
||||
Color rcolor;
|
||||
int rspc = 0;
|
||||
|
||||
bool limg_never_hide = false;
|
||||
bool rimg_never_hide = false;
|
||||
};
|
||||
|
||||
struct DrawLabel : DrawLabelBasic, DrawLabelExt {
|
||||
bool push = false;
|
||||
bool focus = false;
|
||||
bool disabled = false;
|
||||
|
||||
Size GetSize(int txtcx, Size sz1, int lspc, Size sz2, int rspc) const;
|
||||
Size GetSize(int txtcx = INT_MAX) const;
|
||||
|
|
@ -59,8 +70,6 @@ struct DrawLabel {
|
|||
Size Paint(Ctrl *ctrl, Draw& w, int x, int y, int cx, int cy, bool visibleaccesskey = true) const;
|
||||
Size Paint(Draw& w, const Rect& r, bool visibleaccesskey = true) const;
|
||||
Size Paint(Draw& w, int x, int y, int cx, int cy, bool visibleaccesskey = true) const;
|
||||
|
||||
DrawLabel();
|
||||
};
|
||||
|
||||
Image DisabledImage(const Image& img, bool disabled = true);
|
||||
|
|
@ -70,7 +79,11 @@ class LabelBase {
|
|||
protected:
|
||||
virtual void LabelUpdate();
|
||||
|
||||
DrawLabel lbl;
|
||||
DrawLabelBasic lbl;
|
||||
One<DrawLabelExt> ext;
|
||||
|
||||
DrawLabelExt& Ext() { if(!ext) ext.Create() ; return *ext; }
|
||||
DrawLabel Make() const;
|
||||
|
||||
public:
|
||||
LabelBase& SetLeftImage(const Image& bmp1, int spc = 0, bool never_hide = false);
|
||||
|
|
@ -94,7 +107,7 @@ public:
|
|||
|
||||
int GetAlign() const { return lbl.align; }
|
||||
int GetVAlign() const { return lbl.valign; }
|
||||
PaintRect GetPaintRect() const { return lbl.paintrect; }
|
||||
PaintRect GetPaintRect() const { return ext ? ext->paintrect : PaintRect(); }
|
||||
String GetText() const { return lbl.text; }
|
||||
Font GetFont() const { return lbl.font; }
|
||||
Color GetInk() const { return lbl.ink; }
|
||||
|
|
@ -108,6 +121,9 @@ public:
|
|||
Size PaintLabel(Draw& w, int x, int y, int cx, int cy,
|
||||
bool disabled = false, bool push = false, bool focus = false, bool vak = true);
|
||||
Size GetLabelSize() const;
|
||||
|
||||
LabelBase(const LabelBase& src) { lbl = src.lbl; if(src.ext) ext = clone(src.ext); }
|
||||
LabelBase() {}
|
||||
|
||||
virtual ~LabelBase();
|
||||
};
|
||||
|
|
@ -121,13 +137,13 @@ public:
|
|||
virtual void FrameAddSize(Size& sz);
|
||||
|
||||
private:
|
||||
Value coloredge;
|
||||
const Value *edge;
|
||||
const Ctrl *ctrl;
|
||||
Value coloredge;
|
||||
Color color;
|
||||
bool mousein = false;
|
||||
bool push = false;
|
||||
bool button = false;
|
||||
Color color;
|
||||
bool mousein:1;
|
||||
bool push:1;
|
||||
bool button:1;
|
||||
|
||||
public:
|
||||
void Set(const Ctrl *ctrl, const Value *edge, bool active);
|
||||
|
|
@ -135,5 +151,5 @@ public:
|
|||
void Push(bool b) { button = true; push = b; }
|
||||
void SetColor(const Value& ce, Color c) { coloredge = ce; color = c; }
|
||||
|
||||
ActiveEdgeFrame() { edge = NULL; mousein = false; }
|
||||
ActiveEdgeFrame() { edge = NULL; mousein = push = button = false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -799,14 +799,18 @@ void LineEdit::AlignChar() {
|
|||
}
|
||||
}
|
||||
|
||||
Rect LineEdit::GetCaret() const
|
||||
{
|
||||
if(overwrite)
|
||||
return RectC(caretpos.x, caretpos.y + fsz.cy - 2, fsz.cx, 2);
|
||||
else
|
||||
return RectC(caretpos.x, caretpos.y, 2, fsz.cy);
|
||||
}
|
||||
|
||||
void LineEdit::PlaceCaret0(Point p) {
|
||||
Size fsz = GetFontSize();
|
||||
p -= sb;
|
||||
caretpos = Point(p.x * fsz.cx, p.y * fsz.cy);
|
||||
if(overwrite)
|
||||
SetCaret(caretpos.x, caretpos.y + fsz.cy - 2, fsz.cx, 2);
|
||||
else
|
||||
SetCaret(caretpos.x, caretpos.y, 2, fsz.cy);
|
||||
}
|
||||
|
||||
int LineEdit::PlaceCaretNoG(int64 newcursor, bool 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 = false;
|
||||
}
|
||||
}
|
||||
|
||||
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,21 +273,21 @@ 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;
|
||||
}
|
||||
if(WhenPush || WhenClick)
|
||||
if(HasMain())
|
||||
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;
|
||||
|
|
@ -393,7 +454,7 @@ Rect MultiButton::Paint0(Draw& w, bool getcr)
|
|||
Color p = paper;
|
||||
if(frm && style->activeedge && HasFocus())
|
||||
p = SColorHighlight();
|
||||
if(hotpressed && (WhenPush || WhenClick))
|
||||
if(hotpressed && HasMain())
|
||||
p = Nvl(fpaper, paper);
|
||||
if(IsEnabled() && IsEditable())
|
||||
p = Nvl(p, style->paper);
|
||||
|
|
@ -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,8 @@ 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);
|
||||
String tip = GetTextAttr(ATTR_TIP);
|
||||
Ctrl::Tip(h >= 0 && h < GetButtonCount() ? Nvl(Button(h).tip, tip) : tip);
|
||||
if(hl != h) {
|
||||
hl = h;
|
||||
Refresh();
|
||||
|
|
@ -575,12 +637,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,9 +663,9 @@ void MultiButton::LeftDown(Point p, dword flags)
|
|||
}
|
||||
Sync();
|
||||
if(hl >= 0)
|
||||
button[hl].WhenPush();
|
||||
DoPush(hl);
|
||||
else
|
||||
WhenPush();
|
||||
MainPush();
|
||||
}
|
||||
SyncInfo();
|
||||
}
|
||||
|
|
@ -605,11 +675,11 @@ 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();
|
||||
MainClick();
|
||||
}
|
||||
SyncInfo();
|
||||
}
|
||||
|
|
@ -617,7 +687,7 @@ void MultiButton::LeftUp(Point p, dword flags)
|
|||
void MultiButton::MouseLeave()
|
||||
{
|
||||
if(!info.IsOpen()) {
|
||||
hl = Null;
|
||||
hl = NONE;
|
||||
Refresh();
|
||||
SyncInfo();
|
||||
}
|
||||
|
|
@ -625,7 +695,7 @@ void MultiButton::MouseLeave()
|
|||
|
||||
void MultiButton::CancelMode()
|
||||
{
|
||||
hl = Null;
|
||||
hl = NONE;
|
||||
push = false;
|
||||
Refresh();
|
||||
info.Cancel();
|
||||
|
|
@ -633,21 +703,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) && !HasMain();
|
||||
}
|
||||
|
||||
MultiButton& MultiButton::SetDisplay(const Display& d)
|
||||
|
|
@ -718,11 +774,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();
|
||||
}
|
||||
|
|
@ -730,15 +786,32 @@ void MultiButton::PseudoPush(int bi)
|
|||
void MultiButton::PseudoPush()
|
||||
{
|
||||
hl = MAIN;
|
||||
WhenPush();
|
||||
MainPush();
|
||||
Sync();
|
||||
Sleep(50);
|
||||
WhenClick();
|
||||
hl = Null;
|
||||
MainClick();
|
||||
hl = NONE;
|
||||
push = false;
|
||||
Sync();
|
||||
}
|
||||
|
||||
bool MultiButton::HasMain() const
|
||||
{
|
||||
return WhenPush || WhenClick;
|
||||
}
|
||||
|
||||
void MultiButton::MainPush()
|
||||
{
|
||||
WhenPush();
|
||||
}
|
||||
|
||||
void MultiButton::MainClick()
|
||||
{
|
||||
WhenClick();
|
||||
}
|
||||
|
||||
void MultiButton::DropPush() {}
|
||||
|
||||
MultiButton::MultiButton()
|
||||
{
|
||||
Transparent();
|
||||
|
|
@ -749,8 +822,12 @@ MultiButton::MultiButton()
|
|||
push = false;
|
||||
SetFrame(sNullFrame());
|
||||
nobg = false;
|
||||
hl = NONE;
|
||||
droppush = false;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void MultiButtonFrame::FrameAdd(Ctrl& parent)
|
||||
{
|
||||
parent.Add(*this);
|
||||
|
|
|
|||
|
|
@ -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,24 @@ private:
|
|||
|
||||
virtual bool Frame();
|
||||
|
||||
const Display *display;
|
||||
const Convert *convert;
|
||||
DisplayPopup info;
|
||||
Array<SubButton> buttons;
|
||||
|
||||
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;
|
||||
bool droppush:1;
|
||||
|
||||
int FindButton(int px);
|
||||
void Margins(int& l, int& r);
|
||||
|
|
@ -124,13 +125,27 @@ 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;
|
||||
bool HasMain() const;
|
||||
void MainPush();
|
||||
void MainClick();
|
||||
|
||||
friend class SubButton;
|
||||
friend class MultiButtonFrame;
|
||||
|
||||
protected:
|
||||
enum {
|
||||
ATTR_TIP = Ctrl::ATTR_LAST,
|
||||
ATTR_LAST
|
||||
};
|
||||
|
||||
virtual void DropPush();
|
||||
|
||||
public:
|
||||
Event<> WhenPush;
|
||||
Event<> WhenClick;
|
||||
Event<> WhenPush;
|
||||
Event<> WhenClick;
|
||||
|
||||
static const Style& StyleDefault();
|
||||
static const Style& StyleFrame();
|
||||
|
|
@ -145,8 +160,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; }
|
||||
|
|
@ -164,10 +180,12 @@ public:
|
|||
MultiButton& SetConvert(const Convert& c);
|
||||
MultiButton& SetValueCy(int cy);
|
||||
MultiButton& Set(const Value& v, bool update = true);
|
||||
MultiButton& Tip(const char *s) { tip = s; return *this; }
|
||||
MultiButton& Tip(const char *s) { SetTextAttr(ATTR_TIP, s); return *this; }
|
||||
MultiButton& NoBackground(bool b = true);
|
||||
|
||||
MultiButton& SetStyle(const Style& s) { style = &s; Refresh(); return *this; }
|
||||
|
||||
void SetupDropPush() { droppush = true; }
|
||||
|
||||
MultiButton();
|
||||
};
|
||||
|
|
|
|||
321
uppsrc/CtrlLib/PopUpList.cpp
Normal file
321
uppsrc/CtrlLib/PopUpList.cpp
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
#include "CtrlLib.h"
|
||||
#include "CtrlLib.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
CtrlFrame& DropFrame();
|
||||
|
||||
void PopUpList::Clear()
|
||||
{
|
||||
items.Clear();
|
||||
lineinfo.Clear();
|
||||
linedisplay.Clear();
|
||||
cursor = -1;
|
||||
if(popup)
|
||||
popup->ac.Clear();
|
||||
}
|
||||
|
||||
void PopUpList::Remove(int i)
|
||||
{
|
||||
items.Remove(i);
|
||||
if(i < lineinfo.GetCount())
|
||||
lineinfo.Remove(i);
|
||||
if(i < linedisplay.GetCount())
|
||||
linedisplay.Remove(i);
|
||||
if(popup)
|
||||
popup->ac.Remove(i);
|
||||
if(cursor > i)
|
||||
cursor--;
|
||||
}
|
||||
|
||||
void PopUpList::Insert(int i, const Value& v)
|
||||
{
|
||||
items.Insert(i, v);
|
||||
if(i < lineinfo.GetCount())
|
||||
lineinfo.Insert(i, 0x7fff);
|
||||
if(i < linedisplay.GetCount())
|
||||
linedisplay.Insert(i, nullptr);
|
||||
if(popup)
|
||||
popup->ac.Insert(i, Vector<Value>() << v);
|
||||
if(cursor >= i)
|
||||
cursor++;
|
||||
}
|
||||
|
||||
void PopUpList::SetCount(int n)
|
||||
{
|
||||
items.SetCount(n);
|
||||
if(popup)
|
||||
popup->ac.SetCount(n);
|
||||
}
|
||||
|
||||
void PopUpList::AddSeparator()
|
||||
{
|
||||
word& x = lineinfo.At(items.GetCount(), 0x7fff);
|
||||
x |= 0x8000;
|
||||
items.Add(Null);
|
||||
if(popup)
|
||||
popup->ac.AddSeparator();
|
||||
}
|
||||
|
||||
void PopUpList::Add(const Value& v)
|
||||
{
|
||||
items.Add(v);
|
||||
if(popup)
|
||||
popup->ac.Add(v);
|
||||
}
|
||||
|
||||
void PopUpList::SetLineCy(int ii, int cy)
|
||||
{
|
||||
ASSERT(cy >= 0 && cy < 32000);
|
||||
word& x = lineinfo.At(ii, 0x7fff);
|
||||
x = x & 0x8000 | cy;
|
||||
if(popup)
|
||||
popup->ac.SetLineCy(ii, cy);
|
||||
}
|
||||
|
||||
int PopUpList::GetLineCy(int ii) const
|
||||
{
|
||||
if(ii >= 0 && ii < lineinfo.GetCount()) {
|
||||
word h = lineinfo[ii] & 0x7fff;
|
||||
if(h != 0x7fff)
|
||||
return h;
|
||||
}
|
||||
return linecy;
|
||||
}
|
||||
|
||||
bool PopUpList::IsLineEnabled(int ii) const
|
||||
{
|
||||
return !(ii >= 0 && ii < lineinfo.GetCount() && ((lineinfo[ii] & 0x8000) || (lineinfo[ii] & 0x7fff) == 0));
|
||||
}
|
||||
|
||||
void PopUpList::Set(int i, const Value& v)
|
||||
{
|
||||
items.At(i) = v;
|
||||
if(popup)
|
||||
popup->ac.Set(i, 0, v);
|
||||
}
|
||||
|
||||
int PopUpList::Find(const Value& v) const
|
||||
{
|
||||
return FindIndex(items, v);
|
||||
}
|
||||
|
||||
void PopUpList::SetScrollBarStyle(const ScrollBar::Style& s)
|
||||
{
|
||||
sb_style = &s;
|
||||
if(popup)
|
||||
popup->ac.SetScrollBarStyle(*sb_style);
|
||||
}
|
||||
|
||||
void PopUpList::SetLineCy(int cy)
|
||||
{
|
||||
linecy = cy;
|
||||
if(popup)
|
||||
popup->ac.SetLineCy(linecy);
|
||||
}
|
||||
|
||||
void PopUpList::SetDisplay(const Display& d)
|
||||
{
|
||||
display = &d;
|
||||
if(popup)
|
||||
popup->ac.ColumnAt(0).SetDisplay(d);
|
||||
}
|
||||
|
||||
void PopUpList::SetDisplay(int i, const Display& d)
|
||||
{
|
||||
linedisplay.At(i, nullptr) = &d;
|
||||
if(popup)
|
||||
popup->ac.SetDisplay(i, 0, d);
|
||||
}
|
||||
|
||||
const Display& PopUpList::GetDisplay(int i) const
|
||||
{
|
||||
if(i >= 0 && i < linedisplay.GetCount() && linedisplay[i])
|
||||
return *linedisplay[i];
|
||||
return *display;
|
||||
}
|
||||
|
||||
void PopUpList::SetConvert(const Convert& c)
|
||||
{
|
||||
convert = &c;
|
||||
if(popup)
|
||||
popup->ac.ColumnAt(0).SetConvert(c);
|
||||
}
|
||||
|
||||
void PopUpList::SetCursor(int i)
|
||||
{
|
||||
cursor = i;
|
||||
if(popup)
|
||||
popup->ac.SetCursor(i);
|
||||
}
|
||||
|
||||
int PopUpList::GetCursor() const
|
||||
{
|
||||
return popup ? popup->ac.GetCursor() : cursor;
|
||||
}
|
||||
|
||||
bool PopUpList::Key(int c)
|
||||
{
|
||||
// TODO!
|
||||
return false;
|
||||
}
|
||||
|
||||
void PopUpList::PopupCancelMode() {
|
||||
if(popup && !inpopup)
|
||||
DoCancel();
|
||||
}
|
||||
|
||||
void PopUpList::DoClose() {
|
||||
if(!inpopup && popup) {
|
||||
popup->closing = true; // prevent infinite recursion
|
||||
cursor = popup->ac.GetCursor();
|
||||
popup.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void PopUpList::PopupDeactivate() {
|
||||
if(popup) {
|
||||
Ctrl::IgnoreMouseClick();
|
||||
DoCancel();
|
||||
}
|
||||
}
|
||||
|
||||
void PopUpList::PopupArrayCtrl::LeftUp(Point p, dword keyflags)
|
||||
{
|
||||
ArrayCtrl::LeftUp(p, keyflags);
|
||||
list->DoSelect();
|
||||
}
|
||||
|
||||
bool PopUpList::PopupArrayCtrl::Key(dword key, int n)
|
||||
{
|
||||
switch(key) {
|
||||
case K_ENTER:
|
||||
case K_ALT_DOWN:
|
||||
list->DoSelect();
|
||||
return true;
|
||||
case K_ESCAPE:
|
||||
list->DoCancel();
|
||||
return true;
|
||||
case K_UP:
|
||||
if(!IsCursor()) {
|
||||
SetCursor(GetCount() - 1);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case K_DOWN:
|
||||
if(!IsCursor()) {
|
||||
SetCursor(0);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ArrayCtrl::Key(key, n);
|
||||
}
|
||||
|
||||
PopUpList::Popup::Popup(PopUpList *list)
|
||||
: list(list)
|
||||
{
|
||||
ac.list = list;
|
||||
ac.SetFrame(DropFrame());
|
||||
auto& col = ac.AddColumn();
|
||||
if(list->convert)
|
||||
col.SetConvert(*list->convert);
|
||||
col.SetDisplay(*list->display);
|
||||
ac.NoHeader();
|
||||
ac.HeaderTab(0).SetMargin(0);
|
||||
ac.MouseMoveCursor();
|
||||
ac.NoGrid();
|
||||
ac.AutoHideSb();
|
||||
ac.SetLineCy(Draw::GetStdFontCy());
|
||||
for(int i = 0; i < list->items.GetCount(); i++) {
|
||||
Value v = list->items[i];
|
||||
word w = i < list->lineinfo.GetCount() ? list->lineinfo[i] : 0x7fff;
|
||||
if(w & 0x8000)
|
||||
ac.AddSeparator();
|
||||
else
|
||||
ac.Add(v);
|
||||
w &= 0x7fff;
|
||||
if(w != 0x7fff)
|
||||
ac.SetLineCy(i, w);
|
||||
}
|
||||
ac.SetCursor(list->GetCursor());
|
||||
ac.CenterCursor();
|
||||
}
|
||||
|
||||
void PopUpList::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
|
||||
if(inpopup)
|
||||
return;
|
||||
inpopup++;
|
||||
DoClose();
|
||||
popup.Create(this);
|
||||
int h = popup->ac.AddFrameSize(width, min(droplines * popup->ac.GetLineCy(), popup->ac.GetTotalCy())).cy;
|
||||
Rect rt = RectC(x, bottom, width, h);
|
||||
Rect area = Ctrl::GetWorkArea(Point(x, top));
|
||||
bool up = false;
|
||||
if(rt.bottom > area.bottom) {
|
||||
up = true;
|
||||
rt.top = top - h;
|
||||
rt.bottom = rt.top + h;
|
||||
}
|
||||
if(up) {
|
||||
popup->SetRect(Rect(rt.left, rt.bottom - 1, rt.right, rt.bottom));
|
||||
popup->Add(popup->ac.TopPos(0, rt.Height()).LeftPos(0, rt.Width()));
|
||||
}
|
||||
else {
|
||||
popup->SetRect(Rect(rt.left, rt.top, rt.right, rt.top + 1));
|
||||
popup->Add(popup->ac.BottomPos(0, rt.Height()).LeftPos(0, rt.Width()));
|
||||
}
|
||||
if(GUI_PopUpEffect()) {
|
||||
popup->ac.CenterCursor();
|
||||
popup->PopUp(owner, true, true, GUI_DropShadows());
|
||||
popup->ac.SetFocus();
|
||||
Ctrl::ProcessEvents();
|
||||
Animate(*popup, rt, GUIEFFECT_SLIDE);
|
||||
}
|
||||
if(popup && !popup->IsOpen()) {
|
||||
popup->SetRect(rt);
|
||||
if(!popup->IsOpen())
|
||||
popup->PopUp(owner, true, true, GUI_DropShadows());
|
||||
popup->ac.CenterCursor();
|
||||
popup->ac.SetFocus();
|
||||
}
|
||||
inpopup--;
|
||||
}
|
||||
|
||||
void PopUpList::PopUp(Ctrl *owner, int width)
|
||||
{
|
||||
Rect r = owner->GetScreenRect();
|
||||
if(width)
|
||||
r.right = r.left + width;
|
||||
PopUp(owner, r.left, r.top, r.bottom, r.Width());
|
||||
}
|
||||
|
||||
void PopUpList::PopUp(Ctrl *owner)
|
||||
{
|
||||
Rect r = owner->GetScreenRect();
|
||||
PopUp(owner, r.left, r.top, r.bottom, r.Width());
|
||||
}
|
||||
|
||||
void PopUpList::DoSelect()
|
||||
{
|
||||
DoClose();
|
||||
WhenSelect();
|
||||
}
|
||||
|
||||
void PopUpList::DoCancel()
|
||||
{
|
||||
DoClose();
|
||||
WhenCancel();
|
||||
}
|
||||
|
||||
PopUpList::PopUpList() {
|
||||
droplines = 16;
|
||||
inpopup = 0;
|
||||
linecy = Draw::GetStdFontCy();
|
||||
display = &StdDisplay();
|
||||
convert = NULL;
|
||||
}
|
||||
|
||||
PopUpList::~PopUpList() {}
|
||||
|
||||
}
|
||||
|
|
@ -15,7 +15,6 @@ void PopUpTable::PopupCancelMode() {
|
|||
DoClose();
|
||||
WhenCancel();
|
||||
}
|
||||
ArrayCtrl::CancelMode();
|
||||
}
|
||||
|
||||
void PopUpTable::DoClose() {
|
||||
|
|
@ -68,7 +67,6 @@ bool PopUpTable::Key(dword key, int n) {
|
|||
}
|
||||
|
||||
void PopUpTable::PopUp(Ctrl *owner, int x, int top, int bottom, int width) {
|
||||
TimeStop tm;
|
||||
if(inpopup)
|
||||
return;
|
||||
inpopup++;
|
||||
|
|
|
|||
|
|
@ -106,6 +106,10 @@ public:
|
|||
static const Style& StyleScroll();
|
||||
static const Style& StyleNaked();
|
||||
|
||||
static void PaintButton(Draw& w, const Rect& r, const Button::Style& st, int visualstate, bool focus,
|
||||
const String& label, Font font, const Image& img,
|
||||
bool monoimg, int accesskey, bool visibaleaccesskeys, bool disabled);
|
||||
|
||||
Button& SetStyle(const Style& s);
|
||||
Button& AutoStyle();
|
||||
|
||||
|
|
@ -126,45 +130,6 @@ public:
|
|||
|
||||
Color ButtonMonoColor(int i);
|
||||
|
||||
class SpinButtons : public CtrlFrame {
|
||||
public:
|
||||
virtual void FrameLayout(Rect& r);
|
||||
virtual void FrameAddSize(Size& sz);
|
||||
virtual void FrameAdd(Ctrl& ctrl);
|
||||
virtual void FrameRemove();
|
||||
|
||||
public:
|
||||
struct Style : ChStyle<Style> {
|
||||
Button::Style inc;
|
||||
Button::Style dec;
|
||||
int width;
|
||||
int over;
|
||||
bool onsides;
|
||||
};
|
||||
|
||||
private:
|
||||
bool visible;
|
||||
const Style *style;
|
||||
|
||||
public:
|
||||
Button inc;
|
||||
Button dec;
|
||||
|
||||
void Show(bool s = true);
|
||||
bool IsVisible() const { return visible; }
|
||||
|
||||
static const Style& StyleDefault();
|
||||
static const Style& StyleOnSides();
|
||||
|
||||
SpinButtons& SetStyle(const Style& s);
|
||||
|
||||
SpinButtons& OnSides(bool b = true) { return SetStyle(b ? StyleOnSides() : StyleDefault()); }
|
||||
bool IsOnSides() const { return style->onsides; }
|
||||
|
||||
SpinButtons();
|
||||
virtual ~SpinButtons();
|
||||
};
|
||||
|
||||
class Option : public Pusher {
|
||||
public:
|
||||
virtual void Paint(Draw& draw);
|
||||
|
|
@ -183,13 +148,13 @@ protected:
|
|||
protected:
|
||||
Image edge, edged;
|
||||
int option;
|
||||
bool switchimage;
|
||||
bool threestate;
|
||||
bool notnull;
|
||||
bool blackedge;
|
||||
bool showlabel;
|
||||
bool box;
|
||||
bool autobox;
|
||||
bool switchimage:1;
|
||||
bool threestate:1;
|
||||
bool notnull:1;
|
||||
bool blackedge:1;
|
||||
bool showlabel:1;
|
||||
bool box:1;
|
||||
bool autobox:1;
|
||||
Color color;
|
||||
|
||||
void AutoSync();
|
||||
|
|
@ -302,10 +267,10 @@ public:
|
|||
struct Case {
|
||||
String label;
|
||||
Value value;
|
||||
int accesskey = 0;
|
||||
bool enabled = true;
|
||||
int gap = 0;
|
||||
Rect16 rect = Rect16(0, 0, 0, 0);
|
||||
int accesskey = 0;
|
||||
int gap = 0;
|
||||
bool enabled = true;
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
@ -406,3 +371,70 @@ public:
|
|||
DataPusher(const Convert& convert, const Display& display = StdDisplay()); // deprecated
|
||||
DataPusher(const Display& display); // deprecated
|
||||
};
|
||||
|
||||
class SpinButtons : public CtrlFrame {
|
||||
public:
|
||||
virtual void FrameLayout(Rect& r);
|
||||
virtual void FrameAddSize(Size& sz);
|
||||
virtual void FrameAdd(Ctrl& ctrl);
|
||||
virtual void FrameRemove();
|
||||
|
||||
public:
|
||||
struct Style : ChStyle<Style> {
|
||||
Button::Style inc;
|
||||
Button::Style dec;
|
||||
int width;
|
||||
int over;
|
||||
bool onsides;
|
||||
};
|
||||
|
||||
private:
|
||||
bool visible;
|
||||
const Style *style;
|
||||
|
||||
public:
|
||||
Button inc;
|
||||
Button dec;
|
||||
|
||||
void Show(bool s = true);
|
||||
bool IsVisible() const { return visible; }
|
||||
|
||||
static const Style& StyleDefault();
|
||||
static const Style& StyleOnSides();
|
||||
|
||||
SpinButtons& SetStyle(const Style& s);
|
||||
|
||||
SpinButtons& OnSides(bool b = true) { return SetStyle(b ? StyleOnSides() : StyleDefault()); }
|
||||
bool IsOnSides() const { return style->onsides; }
|
||||
|
||||
SpinButtons();
|
||||
virtual ~SpinButtons();
|
||||
};
|
||||
|
||||
struct VirtualButtons {
|
||||
virtual int ButtonCount() const;
|
||||
virtual Rect ButtonRect(int i) const;
|
||||
virtual const Button::Style& ButtonStyle(int i) const;
|
||||
virtual Image ButtonImage(int i) const;
|
||||
virtual bool ButtonMono(int i) const;
|
||||
virtual bool ButtonEnabled(int i) const;
|
||||
|
||||
virtual void ButtonPush(int i);
|
||||
virtual void ButtonRepeat(int i);
|
||||
virtual void ButtonAction(int i);
|
||||
|
||||
int8 pushi = -1;
|
||||
int8 mi = -1;
|
||||
bool buttons_capture = false;
|
||||
|
||||
int FindButton(Point p) const;
|
||||
|
||||
void EndPush(Ctrl *ctrl);
|
||||
|
||||
void ButtonsCancelMode();
|
||||
bool ButtonsMouseEvent(Ctrl *ctrl, int event, Point p);
|
||||
void PaintButtons(Draw& w, Ctrl *ctrl);
|
||||
|
||||
int ButtonVisualState(Ctrl *ctrl, int i);
|
||||
void RefreshButton(Ctrl *ctrl, int i);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,26 +45,11 @@ ScrollBar::ScrollBar() {
|
|||
jump = false;
|
||||
track = true;
|
||||
horz = false;
|
||||
push = light = -1;
|
||||
|
||||
thumbsize = 8;
|
||||
thumbpos = 0;
|
||||
push = light = -1;
|
||||
Add(prev);
|
||||
Add(prev2);
|
||||
Add(next);
|
||||
Add(next2);
|
||||
NoWantFocus();
|
||||
prev.ScrollStyle().NoWantFocus().Transparent();
|
||||
prev.WhenPush = prev.WhenRepeat = callback(this, &ScrollBar::PrevLine);
|
||||
prev.WhenPush << Proxy(WhenLeftClick);
|
||||
prev2.ScrollStyle().NoWantFocus().Transparent();
|
||||
prev2.WhenRepeat = prev.WhenRepeat;
|
||||
prev2.WhenPush = prev.WhenPush;
|
||||
next.ScrollStyle().NoWantFocus().Transparent();
|
||||
next.WhenPush = next.WhenRepeat = callback(this, &ScrollBar::NextLine);
|
||||
next.WhenPush << Proxy(WhenLeftClick);
|
||||
next2.ScrollStyle().NoWantFocus().Transparent();
|
||||
next2.WhenRepeat = next.WhenRepeat;
|
||||
next2.WhenPush = next.WhenPush;
|
||||
style = NULL;
|
||||
SetStyle(StyleDefault());
|
||||
BackPaint();
|
||||
|
|
@ -73,6 +58,93 @@ ScrollBar::ScrollBar() {
|
|||
|
||||
ScrollBar::~ScrollBar() {}
|
||||
|
||||
int ScrollBar::ButtonCount() const
|
||||
{
|
||||
return BUTTONCOUNT;
|
||||
}
|
||||
|
||||
void ScrollBar::Layout() {
|
||||
Size sz = GetSize();
|
||||
Set(pagepos);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
Rect ScrollBar::ButtonRect(int i) const
|
||||
{
|
||||
Size sz = GetSize();
|
||||
if(IsHorz()) {
|
||||
int cc = sz.cx > (3 + style->isleft2 + style->isright2) * style->arrowsize ? style->arrowsize : 0;
|
||||
if(i == PREV)
|
||||
return RectC(0, 0, cc, sz.cy);
|
||||
if(i == NEXT)
|
||||
return RectC(sz.cx - cc, 0, cc, sz.cy);
|
||||
if(i == PREV2 && style->isleft2)
|
||||
return RectC(sz.cx - 2 * cc, 0, cc, sz.cy);
|
||||
if(i == NEXT2 && style->isright2)
|
||||
return RectC(cc, 0, cc, sz.cy);
|
||||
}
|
||||
else {
|
||||
int cc = sz.cy > (3 + style->isup2 + style->isdown2) * style->arrowsize ? style->arrowsize : 0;
|
||||
if(i == PREV)
|
||||
return RectC(0, 0, sz.cx, cc);
|
||||
if(i == NEXT)
|
||||
return RectC(0, sz.cy - cc, sz.cx, cc);
|
||||
if(i == PREV2 && style->isup2)
|
||||
return RectC(0, sz.cy - 2 * cc, sz.cx, cc);
|
||||
if(i == NEXT2 && style->isdown2)
|
||||
return RectC(0, cc, sz.cx, cc);
|
||||
}
|
||||
return Null;
|
||||
}
|
||||
|
||||
bool ScrollBar::ButtonEnabled(int i) const
|
||||
{
|
||||
return is_active || !autodisable;
|
||||
}
|
||||
|
||||
void ScrollBar::ButtonPush(int i)
|
||||
{
|
||||
WhenLeftClick();
|
||||
ButtonRepeat(i);
|
||||
}
|
||||
|
||||
void ScrollBar::ButtonRepeat(int i)
|
||||
{
|
||||
if(i == PREV)
|
||||
PrevLine();
|
||||
if(i == NEXT)
|
||||
NextLine();
|
||||
if(i == PREV2)
|
||||
PrevPage();
|
||||
if(i == NEXT2)
|
||||
NextPage();
|
||||
}
|
||||
|
||||
const Button::Style& ScrollBar::ButtonStyle(int i) const
|
||||
{
|
||||
if(IsHorz()) {
|
||||
if(i == PREV)
|
||||
return style->left;
|
||||
if(i == NEXT)
|
||||
return style->right;
|
||||
if(i == PREV2)
|
||||
return style->left2;
|
||||
if(i == NEXT2)
|
||||
return style->right2;
|
||||
}
|
||||
else {
|
||||
if(i == PREV)
|
||||
return style->up;
|
||||
if(i == NEXT)
|
||||
return style->down;
|
||||
if(i == PREV2)
|
||||
return style->up2;
|
||||
if(i == NEXT2)
|
||||
return style->down2;
|
||||
}
|
||||
return Button::StyleNormal();
|
||||
}
|
||||
|
||||
Rect ScrollBar::Slider(int& cc) const
|
||||
{
|
||||
Size sz = GetSize();
|
||||
|
|
@ -135,20 +207,21 @@ Rect ScrollBar::GetPartRect(int p) const {
|
|||
return h;
|
||||
}
|
||||
|
||||
void ScrollBar::Paint(Draw& w) {
|
||||
void ScrollBar::Paint(Draw& w)
|
||||
{
|
||||
w.DrawRect(GetSize(), style->bgcolor);
|
||||
int cc;
|
||||
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 };
|
||||
|
||||
const Value **l = IsHorz() ? hl : vl;
|
||||
|
||||
if(prev.IsShowEnabled()) {
|
||||
if(is_active || !autodisable) {
|
||||
for(int i = 0; i < 3; i++) {
|
||||
Rect pr = GetPartRect(i);
|
||||
if(i != 2) {
|
||||
|
|
@ -156,12 +229,12 @@ 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();
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
if(style->through)
|
||||
ChPaint(w, sz, l[0][CTRL_DISABLED]);
|
||||
else
|
||||
|
|
@ -169,6 +242,8 @@ void ScrollBar::Paint(Draw& w) {
|
|||
ChPaint(w, cc, 0, sz.cx, sz.cy, l[0][CTRL_DISABLED]);
|
||||
else
|
||||
ChPaint(w, 0, cc, sz.cx, sz.cy, l[0][CTRL_DISABLED]);
|
||||
}
|
||||
PaintButtons(w, this);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -216,6 +291,13 @@ void ScrollBar::Drag(Point p) {
|
|||
Position();
|
||||
}
|
||||
|
||||
Image ScrollBar::MouseEvent(int event, Point p, int zdelta, dword keyflags)
|
||||
{
|
||||
if(ButtonsMouseEvent(this, event, p))
|
||||
return Image::Arrow();
|
||||
return Ctrl::MouseEvent(event, p, zdelta, keyflags);
|
||||
}
|
||||
|
||||
void ScrollBar::LeftDown(Point p, dword) {
|
||||
push = GetMousePart();
|
||||
LLOG("ScrollBar::LeftDown(" << p << ")");
|
||||
|
|
@ -243,6 +325,7 @@ void ScrollBar::LeftDown(Point p, dword) {
|
|||
NextPage();
|
||||
}
|
||||
SetCapture();
|
||||
buttons_capture = false;
|
||||
Refresh();
|
||||
WhenLeftClick();
|
||||
}
|
||||
|
|
@ -289,6 +372,7 @@ void ScrollBar::MouseWheel(Point p, int zdelta, dword keyflags)
|
|||
|
||||
void ScrollBar::CancelMode() {
|
||||
push = light = -1;
|
||||
ButtonsCancelMode();
|
||||
}
|
||||
|
||||
bool ScrollBar::Set(int apagepos) {
|
||||
|
|
@ -330,19 +414,16 @@ bool ScrollBar::Set(int apagepos) {
|
|||
void ScrollBar::Set(int _pagepos, int _pagesize, int _totalsize) {
|
||||
pagesize = _pagesize;
|
||||
totalsize = _totalsize;
|
||||
is_active = totalsize > pagesize && pagesize > 0;
|
||||
|
||||
bool active = totalsize > pagesize && pagesize > 0;
|
||||
if(active != is_active) {
|
||||
Refresh();
|
||||
is_active = active;
|
||||
}
|
||||
if(autohide && is_active != IsShown()) {
|
||||
Show(is_active);
|
||||
WhenVisibility();
|
||||
}
|
||||
if(autodisable) {
|
||||
if(prev.IsEnabled() != is_active)
|
||||
Refresh();
|
||||
prev.Enable(is_active);
|
||||
next.Enable(is_active);
|
||||
prev2.Enable(is_active);
|
||||
next2.Enable(is_active);
|
||||
}
|
||||
Set(_pagepos);
|
||||
}
|
||||
|
||||
|
|
@ -472,38 +553,6 @@ bool ScrollBar::HorzKey(dword key) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ScrollBar::Layout() {
|
||||
Size sz = GetSize();
|
||||
if(IsHorz()) {
|
||||
prev.SetStyle(style->left);
|
||||
next.SetStyle(style->right);
|
||||
prev2.SetStyle(style->left2);
|
||||
next2.SetStyle(style->right2);
|
||||
int cc = sz.cx > (3 + style->isleft2 + style->isright2) * style->arrowsize ? style->arrowsize : 0;
|
||||
prev.SetRect(0, 0, cc, sz.cy);
|
||||
next.SetRect(sz.cx - cc, 0, cc, sz.cy);
|
||||
prev2.Show(style->isleft2);
|
||||
prev2.SetRect(sz.cx - 2 * cc, 0, cc, sz.cy);
|
||||
next2.Show(style->isright2);
|
||||
next2.SetRect(cc, 0, cc, sz.cy);
|
||||
}
|
||||
else {
|
||||
prev.SetStyle(style->up);
|
||||
next.SetStyle(style->down);
|
||||
prev2.SetStyle(style->up2);
|
||||
next2.SetStyle(style->down2);
|
||||
int cc = sz.cy > (3 + style->isup2 + style->isdown2) * style->arrowsize ? style->arrowsize : 0;
|
||||
prev.SetRect(0, 0, sz.cx, cc);
|
||||
next.SetRect(0, sz.cy - cc, sz.cx, cc);
|
||||
prev2.Show(style->isup2);
|
||||
prev2.SetRect(0, sz.cy - 2 * cc, sz.cx, cc);
|
||||
next2.Show(style->isdown2);
|
||||
next2.SetRect(0, cc, sz.cx, cc);
|
||||
}
|
||||
Set(pagepos);
|
||||
Refresh();
|
||||
}
|
||||
|
||||
bool ScrollBar::ScrollInto(int pos, int _linesize) {
|
||||
int new_pos = pagepos;
|
||||
if(pos > new_pos + pagesize - _linesize)
|
||||
|
|
@ -560,14 +609,7 @@ ScrollBar& ScrollBar::AutoHide(bool b) {
|
|||
|
||||
ScrollBar& ScrollBar::AutoDisable(bool b) {
|
||||
autodisable = b;
|
||||
if(!b) {
|
||||
if(!prev.IsEnabled())
|
||||
Refresh();
|
||||
prev.Enable();
|
||||
prev2.Enable();
|
||||
next.Enable();
|
||||
next2.Enable();
|
||||
}
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
class ScrollBar : public FrameCtrl<Ctrl> {
|
||||
class ScrollBar : public FrameCtrl<Ctrl>, private VirtualButtons {
|
||||
public:
|
||||
virtual void Layout();
|
||||
virtual Size GetStdSize() const;
|
||||
|
|
@ -15,6 +15,16 @@ public:
|
|||
virtual void FrameLayout(Rect& r);
|
||||
virtual void FrameAddSize(Size& sz);
|
||||
|
||||
virtual Image MouseEvent(int event, Point p, int zdelta, dword keyflags);
|
||||
|
||||
virtual int ButtonCount() const;
|
||||
virtual Rect ButtonRect(int i) const;
|
||||
virtual const Button::Style& ButtonStyle(int i) const;
|
||||
virtual bool ButtonEnabled(int i) const;
|
||||
|
||||
virtual void ButtonPush(int i);
|
||||
virtual void ButtonRepeat(int i);
|
||||
|
||||
public:
|
||||
struct Style : ChStyle<Style> {
|
||||
Color bgcolor;
|
||||
|
|
@ -30,19 +40,20 @@ public:
|
|||
private:
|
||||
int thumbpos;
|
||||
int thumbsize;
|
||||
bool horz:1;
|
||||
bool jump:1;
|
||||
bool track:1;
|
||||
int delta;
|
||||
int8 push;
|
||||
int8 light;
|
||||
|
||||
Button prev, prev2, next, next2;
|
||||
enum { PREV, PREV2, NEXT, NEXT2, BUTTONCOUNT };
|
||||
// Button prev, prev2, next, next2;
|
||||
int pagepos;
|
||||
int pagesize;
|
||||
int totalsize;
|
||||
int linesize;
|
||||
int minthumb;
|
||||
int8 push;
|
||||
int8 light;
|
||||
bool horz:1;
|
||||
bool jump:1;
|
||||
bool track:1;
|
||||
bool autohide:1;
|
||||
bool autodisable:1;
|
||||
bool is_active:1;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,73 @@
|
|||
|
||||
namespace Upp {
|
||||
|
||||
CH_COLOR(LabelBoxColor, SColorShadow());
|
||||
|
||||
CH_COLOR(LabelBoxTextColor, SColorText());
|
||||
CH_COLOR(LabelBoxDisabledTextColor, SColorDisabled());
|
||||
|
||||
StaticText& StaticText::SetFont(Font font)
|
||||
{
|
||||
SetFontAttr(ATTR_FONT, font);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
StaticText& StaticText::SetInk(Color color)
|
||||
{
|
||||
SetColorAttr(ATTR_INK, color);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
StaticText& StaticText::SetAlign(int align)
|
||||
{
|
||||
SetIntAttr(ATTR_ALIGN, align);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
StaticText& StaticText::SetImage(const Image& img, int spc)
|
||||
{
|
||||
CreateAttr<Image>(ATTR_IMAGE) = img;
|
||||
if(spc)
|
||||
SetIntAttr(ATTR_IMAGE_SPC, spc);
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
StaticText& StaticText::SetText(const char *s)
|
||||
{
|
||||
text = s;
|
||||
Refresh();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void StaticText::MakeDrawLabel(DrawLabel& l) const
|
||||
{
|
||||
l.text = text;
|
||||
l.font = Nvl(GetFontAttr(ATTR_FONT), StdFont());
|
||||
l.ink = Nvl(GetColorAttr(ATTR_INK), SColorText());
|
||||
l.align = Nvl(GetIntAttr(ATTR_ALIGN), ALIGN_LEFT);
|
||||
l.limg = GetAttr<Image>(ATTR_IMAGE);
|
||||
l.lspc = Nvl(GetIntAttr(ATTR_IMAGE_SPC), 0);
|
||||
l.disabled = !IsShowEnabled();
|
||||
l.accesskey = accesskey;
|
||||
if(dynamic_cast<const LabelBox *>(this)) {
|
||||
l.valign = ALIGN_TOP;
|
||||
l.disabledink = LabelBoxDisabledTextColor();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticText::Paint(Draw& w)
|
||||
{
|
||||
DrawLabel l;
|
||||
MakeDrawLabel(l);
|
||||
Size sz = GetSize();
|
||||
if(!IsTransparent())
|
||||
w.DrawRect(0, 0, sz.cx, sz.cy, SColorFace);
|
||||
PaintLabel(this, w, 0, 0, sz.cx, sz.cy, !IsShowEnabled(), false, false, VisibleAccessKeys());
|
||||
|
||||
l.Paint(this, w, sz, VisibleAccessKeys());
|
||||
}
|
||||
|
||||
Size StaticText::GetMinSize() const
|
||||
|
|
@ -15,8 +76,11 @@ Size StaticText::GetMinSize() const
|
|||
return GetLabelSize();
|
||||
}
|
||||
|
||||
void StaticText::LabelUpdate() {
|
||||
Refresh();
|
||||
Size StaticText::GetLabelSize() const
|
||||
{
|
||||
DrawLabel l;
|
||||
MakeDrawLabel(l);
|
||||
return l.GetSize();
|
||||
}
|
||||
|
||||
StaticText::StaticText()
|
||||
|
|
@ -24,13 +88,17 @@ StaticText::StaticText()
|
|||
NoWantFocus();
|
||||
IgnoreMouse();
|
||||
Transparent();
|
||||
SetAlign(ALIGN_LEFT);
|
||||
}
|
||||
|
||||
StaticText::~StaticText()
|
||||
{
|
||||
DeleteAttr<Image>(ATTR_IMAGE);
|
||||
}
|
||||
|
||||
Label& Label::SetText(const char *text)
|
||||
{
|
||||
LabelBase::SetText(text);
|
||||
lbl.accesskey = 0;
|
||||
accesskey = 0;
|
||||
StaticText::SetText(text);
|
||||
noac = false;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -38,14 +106,13 @@ Label& Label::SetText(const char *text)
|
|||
Label& Label::SetLabel(const char *_text)
|
||||
{
|
||||
String text;
|
||||
int accesskey = ExtractAccessKey(_text, text);
|
||||
LabelBase::SetText(text);
|
||||
lbl.accesskey = accesskey;
|
||||
accesskey = ExtractAccessKey(_text, text);
|
||||
StaticText::SetText(text);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Label::HotKey(dword key) {
|
||||
if(CompareAccessKey(lbl.accesskey, key)) {
|
||||
if(CompareAccessKey(accesskey, key)) {
|
||||
IterateFocusForward(this, GetParent());
|
||||
return true;
|
||||
}
|
||||
|
|
@ -54,7 +121,7 @@ bool Label::HotKey(dword key) {
|
|||
|
||||
dword Label::GetAccessKeys() const
|
||||
{
|
||||
return AccessKeyBit(lbl.accesskey);
|
||||
return AccessKeyBit(accesskey);
|
||||
}
|
||||
|
||||
void Label::AssignAccessKeys(dword used)
|
||||
|
|
@ -62,12 +129,12 @@ void Label::AssignAccessKeys(dword used)
|
|||
if(noac)
|
||||
return;
|
||||
Ctrl *next = GetNext();
|
||||
if(!lbl.accesskey && next && next->IsInitFocus()) {
|
||||
if(!accesskey && next && next->IsInitFocus()) {
|
||||
next->AssignAccessKeys(used);
|
||||
if(!next->GetAccessKeysDeep()) {
|
||||
lbl.accesskey = ChooseAccessKey(GetText(), used);
|
||||
if(lbl.accesskey) Refresh();
|
||||
used |= AccessKeyBit(lbl.accesskey);
|
||||
accesskey = ChooseAccessKey(text, used);
|
||||
if(accesskey) Refresh();
|
||||
used |= AccessKeyBit(accesskey);
|
||||
}
|
||||
}
|
||||
Ctrl::AssignAccessKeys(used);
|
||||
|
|
@ -79,16 +146,10 @@ Label::Label() {
|
|||
|
||||
Label::~Label() {}
|
||||
|
||||
CH_COLOR(LabelBoxColor, SColorShadow());
|
||||
|
||||
CH_COLOR(LabelBoxTextColor, SColorText());
|
||||
CH_COLOR(LabelBoxDisabledTextColor, SColorDisabled());
|
||||
|
||||
LabelBox::LabelBox()
|
||||
{
|
||||
color = Null;
|
||||
LabelBase::SetInk(LabelBoxTextColor(), LabelBoxDisabledTextColor());
|
||||
SetVAlign(ALIGN_TOP);
|
||||
SetInk(LabelBoxTextColor());
|
||||
}
|
||||
|
||||
void LabelBox::AssignAccessKeys(dword used)
|
||||
|
|
@ -192,7 +253,9 @@ void LabelBox::Paint(Draw& w)
|
|||
Size lsz = GetLabelSize();
|
||||
int d = lsz.cy >> 1;
|
||||
int ty = sz.cy < 2 * Draw::GetStdFontCy() ? (sz.cy - lsz.cy) / 2 : 0;
|
||||
Size ts = PaintLabel(w, d + DPI(2), ty, sz.cx, lsz.cy, !IsShowEnabled(), false, false, VisibleAccessKeys());
|
||||
DrawLabel l;
|
||||
MakeDrawLabel(l);
|
||||
Size ts = l.Paint(this, w, d + DPI(2), ty, sz.cx, lsz.cy);
|
||||
w.Begin();
|
||||
w.ExcludeClip(d, ty, ts.cx + DPI(4), ts.cy);
|
||||
PaintLabelBox(w, sz, color, d);
|
||||
|
|
|
|||
|
|
@ -1,19 +1,38 @@
|
|||
class StaticText : public Ctrl, public LabelBase {
|
||||
class StaticText : public Ctrl {
|
||||
public:
|
||||
virtual void Paint(Draw& w);
|
||||
virtual Size GetMinSize() const;
|
||||
virtual void LabelUpdate();
|
||||
|
||||
enum {
|
||||
ATTR_INK = Ctrl::ATTR_LAST,
|
||||
ATTR_FONT,
|
||||
ATTR_ALIGN,
|
||||
ATTR_IMAGE,
|
||||
ATTR_IMAGE_SPC,
|
||||
ATTR_LAST,
|
||||
};
|
||||
|
||||
protected:
|
||||
String text;
|
||||
int accesskey = 0;
|
||||
|
||||
void MakeDrawLabel(DrawLabel& l) const;
|
||||
Size GetLabelSize() const;
|
||||
|
||||
public:
|
||||
StaticText& SetFont(Font font) { LabelBase::SetFont(font); return *this; }
|
||||
StaticText& SetInk(Color color) { LabelBase::SetInk(color); return *this; }
|
||||
StaticText& SetAlign(int align) { LabelBase::SetAlign(align); return *this; }
|
||||
StaticText& SetImage(const Image& img, int spc = 0) { LabelBase::SetImage(img, spc); return *this; }
|
||||
StaticText& SetText(const char *text) { LabelBase::SetText(text); return *this; }
|
||||
StaticText& SetFont(Font font);
|
||||
StaticText& SetInk(Color color);
|
||||
StaticText& SetAlign(int align);
|
||||
StaticText& AlignLeft() { return SetAlign(ALIGN_LEFT); }
|
||||
StaticText& AlignCenter() { return SetAlign(ALIGN_CENTER); }
|
||||
StaticText& AlignRight() { return SetAlign(ALIGN_RIGHT); }
|
||||
StaticText& SetImage(const Image& img, int spc = 0);
|
||||
StaticText& SetText(const char *text);
|
||||
|
||||
StaticText& operator=(const char *s) { SetText(s); return *this; }
|
||||
|
||||
StaticText();
|
||||
~StaticText();
|
||||
};
|
||||
|
||||
class Label : public StaticText {
|
||||
|
|
|
|||
|
|
@ -299,6 +299,7 @@ public:
|
|||
virtual void Layout();
|
||||
virtual void RefreshLine(int i);
|
||||
virtual Font GetPreeditFont();
|
||||
virtual Rect GetCaret() const;
|
||||
|
||||
protected:
|
||||
virtual void SetSb();
|
||||
|
|
@ -507,6 +508,8 @@ public:
|
|||
virtual void DragLeave();
|
||||
virtual void LeftDrag(Point p, dword flags);
|
||||
|
||||
virtual Rect GetCaret() const;
|
||||
|
||||
protected:
|
||||
virtual void ClearLines();
|
||||
virtual void InsertLines(int line, int count);
|
||||
|
|
@ -527,6 +530,7 @@ protected:
|
|||
ScrollBar sb;
|
||||
int cx;
|
||||
bool updownleave, eofline;
|
||||
Rect caret;
|
||||
|
||||
struct Fmt {
|
||||
FontInfo fi;
|
||||
|
|
|
|||
113
uppsrc/CtrlLib/VirtualButtons.cpp
Normal file
113
uppsrc/CtrlLib/VirtualButtons.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
#include "CtrlLib.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
int VirtualButtons::ButtonCount() const { return 0; }
|
||||
Rect VirtualButtons::ButtonRect(int i) const { return Null; }
|
||||
const Button::Style& VirtualButtons::ButtonStyle(int i) const { return Button::StyleEdge(); }
|
||||
Image VirtualButtons::ButtonImage(int i) const { return Null; }
|
||||
bool VirtualButtons::ButtonEnabled(int i) const { return true; }
|
||||
bool VirtualButtons::ButtonMono(int i) const { return false; }
|
||||
|
||||
void VirtualButtons::ButtonPush(int i) {}
|
||||
void VirtualButtons::ButtonRepeat(int i) {}
|
||||
void VirtualButtons::ButtonAction(int i) {}
|
||||
|
||||
int VirtualButtons::FindButton(Point p) const
|
||||
{
|
||||
for(int i = 0; i < ButtonCount(); i++)
|
||||
if(ButtonRect(i).Contains(p))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int VirtualButtons::ButtonVisualState(Ctrl *ctrl, int i)
|
||||
{
|
||||
if(ctrl->HasCapture() && !buttons_capture)
|
||||
return CTRL_NORMAL;
|
||||
if(ButtonEnabled(i)) {
|
||||
if(i == pushi)
|
||||
return CTRL_PRESSED;
|
||||
if(ctrl->HasMouseIn(ButtonRect(i)))
|
||||
return CTRL_HOT;
|
||||
return CTRL_NORMAL;
|
||||
}
|
||||
return CTRL_DISABLED;
|
||||
}
|
||||
|
||||
void VirtualButtons::PaintButtons(Draw& w, Ctrl *ctrl)
|
||||
{
|
||||
for(int i = 0; i < ButtonCount(); i++) {
|
||||
Button::PaintButton(w, ButtonRect(i), ButtonStyle(i), ButtonVisualState(ctrl, i), false,
|
||||
String(), StdFont(), ButtonImage(i),
|
||||
ButtonMono(i), 0, false, !ButtonEnabled(i));
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualButtons::EndPush(Ctrl *ctrl)
|
||||
{
|
||||
int i = pushi;
|
||||
pushi = -1;
|
||||
RefreshButton(ctrl, i);
|
||||
}
|
||||
|
||||
void VirtualButtons::RefreshButton(Ctrl *ctrl, int i)
|
||||
{
|
||||
if(i >= 0)
|
||||
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);
|
||||
RefreshButton(ctrl, mi = i);
|
||||
}
|
||||
switch(event) {
|
||||
case Ctrl::LEFTDOWN:
|
||||
case Ctrl::LEFTDOUBLE:
|
||||
case Ctrl::LEFTTRIPLE:
|
||||
pushi = i;
|
||||
if(pushi >= 0) {
|
||||
ButtonPush(i);
|
||||
ctrl->SetCapture();
|
||||
buttons_capture = true;
|
||||
}
|
||||
else
|
||||
EndPush(ctrl);
|
||||
RefreshButton(ctrl, pushi);
|
||||
break;
|
||||
case Ctrl::MOUSEMOVE:
|
||||
if(ctrl->HasCapture() && i != pushi) {
|
||||
RefreshButton(ctrl, pushi);
|
||||
pushi = i;
|
||||
}
|
||||
break;
|
||||
case Ctrl::LEFTREPEAT:
|
||||
if(i >= 0)
|
||||
ButtonRepeat(i);
|
||||
break;
|
||||
case Ctrl::LEFTUP:
|
||||
int ii = pushi;
|
||||
if(ii >= 0) {
|
||||
EndPush(ctrl);
|
||||
ctrl->ReleaseCapture();
|
||||
buttons_capture = false;
|
||||
ButtonAction(ii);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return i >= 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -9,218 +9,231 @@ topic "Static widgets";
|
|||
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
|
||||
[b42;2 $$9,9#13035079074754324216151401829390:normal]
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[{_}%EN-US
|
||||
[s0; [*+150 Static widgets]&]
|
||||
[{_}
|
||||
[s0;%% [*+150 Static widgets]&]
|
||||
[s3;%% &]
|
||||
[ {{10000@3 [s0;%% [*@(229)4 StaticText]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:StaticText`:`:class: [@(0.0.255)3 class][3 _][*3 StaticText][3 _:_][@(0.0.255)3 public][3 _][*@3;3 C
|
||||
trl][3 , ][@(0.0.255)3 public][3 _][*@3;3 LabelBase]&]
|
||||
[s9;%% Static text.&]
|
||||
[s3; &]
|
||||
[ {{10000@3 [s0; [*@(229)4 StaticText]]}}&]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s1;:StaticText`:`:class:%- [@(0.0.255)3 class][3 _][*3 StaticText][3 _:_][@(0.0.255)3 public][3 _
|
||||
][*@3;3 Ctrl][3 , ][@(0.0.255)3 public][3 _][*@3;3 LabelBase]&]
|
||||
[s9; Static text.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:StaticText`:`:SetFont`(Font`):%- [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
[s5;:StaticText`:`:SetFont`(Font`): [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* SetFont]([_^Font^ Font]_[*@3 font])&]
|
||||
[s2; Sets the [%-*@3 font] of text.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:StaticText`:`:SetInk`(Color`):%- [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
[s2;%% Sets the [%-*@3 font] of text.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:StaticText`:`:SetInk`(Color`): [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* SetInk]([_^Color^ Color]_[*@3 color])&]
|
||||
[s2; Sets the [%-*@3 color] of text.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:StaticText`:`:SetAlign`(int`):%- [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
[s2;%% Sets the [%-*@3 color] of text.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:StaticText`:`:SetAlign`(int`): [@(0.0.255) virtual] [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* SetAlign]([@(0.0.255) int]_[*@3 align])&]
|
||||
[s2; Sets alignment [%-*@3 align]. Allowed values are ALIGN`_LEFT,
|
||||
[s2;%% Sets alignment [%-*@3 align]. Allowed values are ALIGN`_LEFT,
|
||||
ALIGN`_CENTER, ALIGN`_RIGHT.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:StaticText`:`:AlignLeft`(`): [_^Upp`:`:StaticText^ StaticText][@(0.0.255) `&]_
|
||||
[* AlignLeft]()&]
|
||||
[s2;%% Same as SetAlign(ALIGN`_LEFT).&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:StaticText`:`:SetImage`(const Image`&`,int`):%- [@(0.0.255) virtual]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:StaticText`:`:AlignCenter`(`): [_^Upp`:`:StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* AlignCenter]()&]
|
||||
[s2;%% Same as SetAlign(ALIGN`_CENTER).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:StaticText`:`:AlignRight`(`): [_^Upp`:`:StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* AlignRight]()&]
|
||||
[s2;%% Same as SetAlign(ALIGN`_RIGHT).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:StaticText`:`:SetImage`(const Image`&`,int`): [@(0.0.255) virtual]
|
||||
[_^StaticText^ StaticText][@(0.0.255) `&]_[* SetImage]([@(0.0.255) const]_[_^Image^ Image][@(0.0.255) `&
|
||||
]_[*@3 img], [@(0.0.255) int]_[*@3 spc]_`=_[@3 0])&]
|
||||
[s2; Sets the Image to be displayed before the text. [%-*@3 spc] is
|
||||
space between the text and Image.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:StaticText`:`:SetText`(const char`*`):%- [@(0.0.255) virtual]
|
||||
[_^StaticText^ StaticText][@(0.0.255) `&]_[* SetText]([@(0.0.255) const]_[@(0.0.255) char]_
|
||||
`*[*@3 text])&]
|
||||
[s5;:StaticText`:`:operator`=`(const char`*`):%- [_^StaticText^ StaticText][@(0.0.255) `&
|
||||
]_[* operator`=]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s])&]
|
||||
[s2; Sets [%-*@3 text]. `"`\1`" at the beginning of text activates
|
||||
[s2;%% Sets the Image to be displayed before the text. [%-*@3 spc]
|
||||
is space between the text and Image.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:StaticText`:`:SetText`(const char`*`): [@(0.0.255) virtual] [_^StaticText^ StaticTex
|
||||
t][@(0.0.255) `&]_[* SetText]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 text])&]
|
||||
[s5;:StaticText`:`:operator`=`(const char`*`): [_^StaticText^ StaticText][@(0.0.255) `&]_
|
||||
[* operator`=]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s])&]
|
||||
[s2;%% Sets [%-*@3 text]. `"`\1`" at the beginning of text activates
|
||||
QTF.&]
|
||||
[s3; &]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 Label]]}}&]
|
||||
[s3; &]
|
||||
[s1;:Label`:`:class:%- [@(0.0.255)3 class][3 _][*3 Label][3 _:_][@(0.0.255)3 public][3 _][*@3;3 Stat
|
||||
icText]&]
|
||||
[s9; Generally used to label other widgets. Differs from StaticText
|
||||
[ {{10000@3 [s0;%% [*@(229)4 Label]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:Label`:`:class: [@(0.0.255)3 class][3 _][*3 Label][3 _:_][@(0.0.255)3 public][3 _][*@3;3 Static
|
||||
Text]&]
|
||||
[s9;%% Generally used to label other widgets. Differs from StaticText
|
||||
by implementing hotkey processing. Hotkeys are assigned automatically
|
||||
by U`+`+ library, however they can also by preassigned using
|
||||
`'`&`' character.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:Label`:`:SetText`(const char`*`):%- [@(0.0.255) virtual] [_^Label^ Label][@(0.0.255) `&
|
||||
]_[* SetText]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 text])&]
|
||||
[s5;:Label`:`:operator`=`(const char`*`):%- [@(0.0.255) virtual] [_^Label^ Label][@(0.0.255) `&
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:Label`:`:SetText`(const char`*`): [@(0.0.255) virtual] [_^Label^ Label][@(0.0.255) `&]_
|
||||
[* SetText]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 text])&]
|
||||
[s5;:Label`:`:operator`=`(const char`*`): [@(0.0.255) virtual] [_^Label^ Label][@(0.0.255) `&
|
||||
]_[* operator`=]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s])&]
|
||||
[s2; Sets the text. Ignores `'`&`' used to mark hotkeys.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:Label`:`:SetLabel`(const char`*`):%- [_^Label^ Label][@(0.0.255) `&]_[* SetLabel]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 lbl])&]
|
||||
[s2; Sets the text, `'`&`' marks hotkeys.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 LabelBox]]}}&]
|
||||
[s3; &]
|
||||
[s1;:LabelBox`:`:class:%- [@(0.0.255)3 class][3 _][*3 LabelBox][3 _:_][@(0.0.255)3 public][3 _][*@3;3 L
|
||||
abel]&]
|
||||
[s9; Rectangular static widget used to visually group other widgets.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:LabelBox`:`:operator`=`(const char`*`):%- [@(0.0.255) virtual]
|
||||
[_^LabelBox^ LabelBox][@(0.0.255) `&]_[* operator`=]([@(0.0.255) const]_[@(0.0.255) char]_`*
|
||||
[*@3 s])&]
|
||||
[s2; Assigns the text of LabelBox.&]
|
||||
[s3; &]
|
||||
[s2;%% Sets the text. Ignores `'`&`' used to mark hotkeys.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:LabelBox`:`:SetColor`(Color`):%- [_^LabelBox^ LabelBox][@(0.0.255) `&]_[* SetColor]([_^Color^ C
|
||||
olor]_[*@3 c])&]
|
||||
[s2; Sets the color of LabelBox.&]
|
||||
[s5;:Label`:`:SetLabel`(const char`*`): [_^Label^ Label][@(0.0.255) `&]_[* SetLabel]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 lbl])&]
|
||||
[s2;%% Sets the text, `'`&`' marks hotkeys.&]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[ {{10000@3 [s0;%% [*@(229)4 LabelBox]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:LabelBox`:`:class: [@(0.0.255)3 class][3 _][*3 LabelBox][3 _:_][@(0.0.255)3 public][3 _][*@3;3 L
|
||||
abel]&]
|
||||
[s9;%% Rectangular static widget used to visually group other widgets.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 ParentCtrl]]}}&]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s1;:ParentCtrl`:`:class:%- [@(0.0.255)3 class][3 _][*3 ParentCtrl][3 _:_][@(0.0.255)3 public][3 _
|
||||
][*@3;3 Ctrl]&]
|
||||
[s9; This class is supposed to be used as logical parent in situation
|
||||
[s5;:LabelBox`:`:operator`=`(const char`*`): [@(0.0.255) virtual] [_^LabelBox^ LabelBox][@(0.0.255) `&
|
||||
]_[* operator`=]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 s])&]
|
||||
[s2;%% Assigns the text of LabelBox.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:LabelBox`:`:SetColor`(Color`): [_^LabelBox^ LabelBox][@(0.0.255) `&]_[* SetColor]([_^Color^ C
|
||||
olor]_[*@3 c])&]
|
||||
[s2;%% Sets the color of LabelBox.&]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[ {{10000@3 [s0;%% [*@(229)4 ParentCtrl]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:ParentCtrl`:`:class: [@(0.0.255)3 class][3 _][*3 ParentCtrl][3 _:_][@(0.0.255)3 public][3 _][*@3;3 C
|
||||
trl]&]
|
||||
[s9;%% This class is supposed to be used as logical parent in situation
|
||||
when more widgets are to be grouped together. The only difference
|
||||
from Ctrl is that ParentCtrl activates Transparent in constructor.&]
|
||||
[s3; &]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 StaticRect]]}}&]
|
||||
[s3; &]
|
||||
[s1;:StaticRect`:`:class:%- [@(0.0.255)3 class][3 _][*3 StaticRect][3 _:_][@(0.0.255)3 public][3 _
|
||||
][*@3;3 Ctrl]&]
|
||||
[s9; Widget completely filled with single color.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:StaticRect`:`:Color`(class Color`):%- [_^StaticRect^ StaticRect][@(0.0.255) `&]_[* Col
|
||||
or]([@(0.0.255) class]_[* Color]_[*@3 c])&]
|
||||
[s2; The color. Default is SColorFace.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 ImageCtrl]]}}&]
|
||||
[s3; &]
|
||||
[s1;:ImageCtrl`:`:class:%- [@(0.0.255)3 class][3 _][*3 ImageCtrl][3 _:_][@(0.0.255)3 public][3 _][*@3;3 C
|
||||
[ {{10000@3 [s0;%% [*@(229)4 StaticRect]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:StaticRect`:`:class: [@(0.0.255)3 class][3 _][*3 StaticRect][3 _:_][@(0.0.255)3 public][3 _][*@3;3 C
|
||||
trl]&]
|
||||
[s9; Display raster Image. Image is centered in the widget rectangle.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:ImageCtrl`:`:SetImage`(const Image`&`):%- [_^ImageCtrl^ ImageCtrl][@(0.0.255) `&]_[* S
|
||||
etImage]([@(0.0.255) const]_[_^Image^ Image][@(0.0.255) `&]_[*@3 `_img])&]
|
||||
[s2; Sets the image.&]
|
||||
[s9;%% Widget completely filled with single color.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 DrawingCtrl]]}}&]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s1;:DrawingCtrl`:`:class:%- [@(0.0.255)3 class][3 _][*3 DrawingCtrl][3 _:_][@(0.0.255)3 public][3 _
|
||||
[s5;:StaticRect`:`:Color`(class Color`): [_^StaticRect^ StaticRect][@(0.0.255) `&]_[* Color
|
||||
]([@(0.0.255) class]_[* Color]_[*@3 c])&]
|
||||
[s2;%% The color. Default is SColorFace.&]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[ {{10000@3 [s0;%% [*@(229)4 ImageCtrl]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:ImageCtrl`:`:class: [@(0.0.255)3 class][3 _][*3 ImageCtrl][3 _:_][@(0.0.255)3 public][3 _][*@3;3 C
|
||||
trl]&]
|
||||
[s9;%% Display raster Image. Image is centered in the widget rectangle.&]
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:ImageCtrl`:`:SetImage`(const Image`&`): [_^ImageCtrl^ ImageCtrl][@(0.0.255) `&]_[* Set
|
||||
Image]([@(0.0.255) const]_[_^Image^ Image][@(0.0.255) `&]_[*@3 `_img])&]
|
||||
[s2;%% Sets the image.&]
|
||||
[s3;%% &]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[ {{10000@3 [s0;%% [*@(229)4 DrawingCtrl]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:DrawingCtrl`:`:class: [@(0.0.255)3 class][3 _][*3 DrawingCtrl][3 _:_][@(0.0.255)3 public][3 _
|
||||
][*@3;3 Ctrl]&]
|
||||
[s9; Displays Drawing.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:DrawingCtrl`:`:Background`(Color`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* Backg
|
||||
round]([_^Color^ Color]_[*@3 color])&]
|
||||
[s2; Sets background [%-*@3 color]. Default is white.&]
|
||||
[s9;%% Displays Drawing.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:DrawingCtrl`:`:Get`(`)const:%- [_^Drawing^ Drawing]_[* Get]()_[@(0.0.255) const]&]
|
||||
[s2; Returns Drawing assigned to Picture.&]
|
||||
[s3;%- &]
|
||||
[s4;%- &]
|
||||
[s5;:DrawingCtrl`:`:KeepRatio`(bool`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* KeepRat
|
||||
io]([@(0.0.255) bool]_[*@3 keep]_`=_[@(0.0.255) true])&]
|
||||
[s2; If active, Picture keeps the aspect ratio of Drawing. Default
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:DrawingCtrl`:`:Background`(Color`): [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* Backgro
|
||||
und]([_^Color^ Color]_[*@3 color])&]
|
||||
[s2;%% Sets background [%-*@3 color]. Default is white.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:DrawingCtrl`:`:Get`(`)const: [_^Drawing^ Drawing]_[* Get]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns Drawing assigned to Picture.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:DrawingCtrl`:`:KeepRatio`(bool`): [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* KeepRatio
|
||||
]([@(0.0.255) bool]_[*@3 keep]_`=_[@(0.0.255) true])&]
|
||||
[s2;%% If active, Picture keeps the aspect ratio of Drawing. Default
|
||||
is on.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:DrawingCtrl`:`:NoKeepRatio`(`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* NoKeepRat
|
||||
io]()&]
|
||||
[s2; Do not keep aspect ratio.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:DrawingCtrl`:`:Set`(const Drawing`&`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* Se
|
||||
t]([@(0.0.255) const]_[_^Drawing^ Drawing][@(0.0.255) `&]_[*@3 `_picture])&]
|
||||
[s5;:DrawingCtrl`:`:operator`=`(const Drawing`&`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:DrawingCtrl`:`:NoKeepRatio`(`): [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* NoKeepRatio
|
||||
]()&]
|
||||
[s2;%% Do not keep aspect ratio.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:DrawingCtrl`:`:Set`(const Drawing`&`): [_^Picture^ DrawingCtrl][@(0.0.255) `&]_[* Set](
|
||||
[@(0.0.255) const]_[_^Drawing^ Drawing][@(0.0.255) `&]_[*@3 `_picture])&]
|
||||
[s5;:DrawingCtrl`:`:operator`=`(const Drawing`&`): [_^Picture^ DrawingCtrl][@(0.0.255) `&
|
||||
]_[* operator`=]([@(0.0.255) const]_[_^Drawing^ Drawing][@(0.0.255) `&]_[*@3 `_picture])&]
|
||||
[s2; Assigns the Drawing.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:DrawingCtrl`:`:operator`=`(const Painting`&`):%- [_^Picture^ DrawingCtrl][@(0.0.255) `&
|
||||
[s2;%% Assigns the Drawing.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:DrawingCtrl`:`:operator`=`(const Painting`&`): [_^Picture^ DrawingCtrl][@(0.0.255) `&
|
||||
]_[* operator`=]([@(0.0.255) const]_[_^Painting^ Painting][@(0.0.255) `&]_[*@3 `_picture])&]
|
||||
[s2; Assigns [%-*@3 `_picture], converted to Drawing.&]
|
||||
[s2;%% Assigns [%-*@3 `_picture], converted to Drawing.&]
|
||||
[s0;%% &]
|
||||
[s0;%% &]
|
||||
[s0; &]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@3 [s0; [*@(229)4 SeparatorCtrl]]}}&]
|
||||
[s3; &]
|
||||
[s1;:SeparatorCtrl`:`:class:%- [@(0.0.255)3 class][3 _][*3 SeparatorCtrl][3 _:_][@(0.0.255)3 pub
|
||||
lic][3 _][*@3;3 Ctrl]&]
|
||||
[s9; Horizontal or vertical separator line. Direction depends on
|
||||
[ {{10000@3 [s0;%% [*@(229)4 SeparatorCtrl]]}}&]
|
||||
[s3;%% &]
|
||||
[s1;:SeparatorCtrl`:`:class: [@(0.0.255)3 class][3 _][*3 SeparatorCtrl][3 _:_][@(0.0.255)3 publi
|
||||
c][3 _][*@3;3 Ctrl]&]
|
||||
[s9;%% Horizontal or vertical separator line. Direction depends on
|
||||
aspect ratio.&]
|
||||
[s3;%- &]
|
||||
[s0;%- &]
|
||||
[ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&]
|
||||
[s3;%- &]
|
||||
[s5;:SeparatorCtrl`:`:Margin`(int`):%- [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&]_[* M
|
||||
argin]([@(0.0.255) int]_[*@3 w])&]
|
||||
[s2; Sets the left`-right (for horizontal separator) or top`-bottom
|
||||
[s3; &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:SeparatorCtrl`:`:Margin`(int`): [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&]_[* Mar
|
||||
gin]([@(0.0.255) int]_[*@3 w])&]
|
||||
[s2;%% Sets the left`-right (for horizontal separator) or top`-bottom
|
||||
margin. Default value is 2.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:SeparatorCtrl`:`:Margin`(int`,int`):%- [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&
|
||||
]_[* Margin]([@(0.0.255) int]_[*@3 l], [@(0.0.255) int]_[*@3 r])&]
|
||||
[s2; Sets the top`-right (for horizontal separator) or top`-bottom
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:SeparatorCtrl`:`:Margin`(int`,int`): [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&]_
|
||||
[* Margin]([@(0.0.255) int]_[*@3 l], [@(0.0.255) int]_[*@3 r])&]
|
||||
[s2;%% Sets the top`-right (for horizontal separator) or top`-bottom
|
||||
to [%-*@3 l] and [%-*@3 r], in that order. Default value is 2.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:SeparatorCtrl`:`:SetSize`(int`):%- [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&]_[* S
|
||||
etSize]([@(0.0.255) int]_[*@3 w])&]
|
||||
[s2; Sets the size returned by GetMinSize `- included to affect the
|
||||
way how widget is treated in BarCtrl. Default value is 7.&]
|
||||
[s3; &]
|
||||
[s4;%- &]
|
||||
[s5;:SeparatorCtrl`:`:SetStyle`(const SeparatorCtrl`:`:Style`&`):%- [_^SeparatorCtrl^ S
|
||||
eparatorCtrl][@(0.0.255) `&]_[* SetStyle]([@(0.0.255) const]_[_^SeparatorCtrl`:`:Style^ S
|
||||
tyle][@(0.0.255) `&]_[*@3 s])&]
|
||||
[s2; Sets the visual style to SeparatorCtrl`::Style [%-*@3 s]. The style
|
||||
is a simple structure with two fields:&]
|
||||
[s7; [*@5 l1]-|the first margin&]
|
||||
[s7;%- [*@5 l2]-|the second margin&]
|
||||
[s3; &]
|
||||
[s0; ]]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:SeparatorCtrl`:`:SetSize`(int`): [_^SeparatorCtrl^ SeparatorCtrl][@(0.0.255) `&]_[* Se
|
||||
tSize]([@(0.0.255) int]_[*@3 w])&]
|
||||
[s2;%% Sets the size returned by GetMinSize `- included to affect
|
||||
the way how widget is treated in BarCtrl. Default value is 7.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:SeparatorCtrl`:`:SetStyle`(const SeparatorCtrl`:`:Style`&`): [_^SeparatorCtrl^ Sep
|
||||
aratorCtrl][@(0.0.255) `&]_[* SetStyle]([@(0.0.255) const]_[_^SeparatorCtrl`:`:Style^ Sty
|
||||
le][@(0.0.255) `&]_[*@3 s])&]
|
||||
[s2;%% Sets the visual style to SeparatorCtrl`::Style [%-*@3 s]. The
|
||||
style is a simple structure with two fields:&]
|
||||
[s7;%% [*@5 l1]-|the first margin&]
|
||||
[s7; [*@5 l2]-|the second margin&]
|
||||
[s3;%% &]
|
||||
[s0;%% ]]
|
||||
|
|
@ -94,14 +94,6 @@ is active.&]
|
|||
[s5;:Upp`:`:WithSpin`:`:NoKeySpin`(`):%- [_^Upp`:`:WithSpin^ WithSpin][@(0.0.255) `&]_[* No
|
||||
KeySpin]()&]
|
||||
[s2; Same as KeySpin(false).&]
|
||||
[s3;%- &]
|
||||
[s4; &]
|
||||
[s5;:WithSpin`:`:SpinButtonsObject`(`):%- [_^SpinButtons^ SpinButtons][@(0.0.255) `&]_[* Sp
|
||||
inButtonsObject]()&]
|
||||
[s5;:WithSpin`:`:SpinButtonsObject`(`)const:%- [@(0.0.255) const]_[_^SpinButtons^ SpinBut
|
||||
tons][@(0.0.255) `&]_[* SpinButtonsObject]()_[@(0.0.255) const]&]
|
||||
[s2; Returns a reference to internal SpinButtons object.&]
|
||||
[s0; &]
|
||||
[s0;%- &]
|
||||
[ {{10000@(113.42.0) [s0; [*@7;4 Predefined WithSpin widgets]]}}&]
|
||||
[s3;%- &]
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class FontInfo;
|
|||
|
||||
inline
|
||||
bool PreferColorEmoji(int c)
|
||||
{ // for these codepoints we prefer replacemnet color emoji even if glyphs is in the font
|
||||
{ // for these codepoints we prefer replacement color emoji even if glyphs is in the font
|
||||
return c >= 0x2600 && c <= 0x27ef || c >= 0x1f004 && c <= 0x1f251 || c >= 0x1f300 && c <= 0x1faf6;
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +211,8 @@ public:
|
|||
|
||||
operator Value() const { return RichToValue(*this); }
|
||||
Font(const Value& q) { *this = q.Get<Font>(); }
|
||||
|
||||
static Font FromInt64(int64 q) { Font fnt; fnt.data = q; return fnt; }
|
||||
|
||||
// BW compatibility
|
||||
FontInfo Info() const;
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ void Image::Serialize(Stream& s)
|
|||
p2 = spot2;
|
||||
s % p2;
|
||||
}
|
||||
if(sz.cx < 0 || sz.cy < 0)
|
||||
s.LoadError();
|
||||
int64 len = (int64)sz.cx * (int64)sz.cy * (int64)sizeof(RGBA);
|
||||
if(s.IsLoading()) {
|
||||
if(len) {
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ Rect RichEdit::PlaceCaret()
|
|||
Rect rr = Rect(zoom * cursorc.left, GetPosY(cursorc), zoom * cursorc.right,
|
||||
GetPosY(PageY(cursorc.page, cursorc.bottom)));
|
||||
if(objectpos >= 0) {
|
||||
KillCaret();
|
||||
caret = Null;
|
||||
return rr;
|
||||
}
|
||||
if(!IsNull(objectrect)) {
|
||||
|
|
@ -272,12 +272,17 @@ Rect RichEdit::PlaceCaret()
|
|||
Refresh();
|
||||
}
|
||||
if(IsSelection())
|
||||
KillCaret();
|
||||
caret = Null;
|
||||
else
|
||||
SetCaret(GetCaretRect(cursorc));
|
||||
caret = GetCaretRect(cursorc);
|
||||
return rr;
|
||||
}
|
||||
|
||||
Rect RichEdit::GetCaret() const
|
||||
{
|
||||
return caret;
|
||||
}
|
||||
|
||||
void RichEdit::SetupRuler()
|
||||
{
|
||||
Zoom zoom = GetZoom();
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ public:
|
|||
virtual String GetSelectionData(const String& fmt) const;
|
||||
virtual Point GetPreedit();
|
||||
virtual Font GetPreeditFont();
|
||||
virtual Rect GetCaret() const;
|
||||
|
||||
private:
|
||||
virtual int GetCharAt(int64 i) const { return GetChar((int)i); }
|
||||
|
|
@ -277,6 +278,7 @@ private:
|
|||
static int fixedlang;
|
||||
RichObject bar_object;
|
||||
String bar_fieldparam;
|
||||
Rect caret;
|
||||
|
||||
WithRichFindReplaceLayout<TopWindow> findreplace;
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ void RichPara::StorePart::Store(Lines& lines, const Part& part, int pinc)
|
|||
h->descent = max(h->ydelta, 0);
|
||||
h->external = 0;
|
||||
lines.object.Add(part.object);
|
||||
h->object = &lines.object.Top();
|
||||
h->object = &lines.object.Top();
|
||||
h++;
|
||||
*t++ = 'x';
|
||||
*p++ = pos;
|
||||
|
|
|
|||
|
|
@ -2710,7 +2710,7 @@ void TabBar::Serialize(Stream& s)
|
|||
int version = 1;
|
||||
s / version;
|
||||
|
||||
s % id;
|
||||
s % id;
|
||||
s % crosses;
|
||||
s % crosses_side;
|
||||
s % grouping;
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@ bool Ctrl::GuiPlatformSetFullRefreshSpecial()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Ctrl::PaintCaret(SystemDraw& w)
|
||||
{
|
||||
}
|
||||
|
||||
String GuiPlatformGetKeyDesc(dword key)
|
||||
{
|
||||
return Null;
|
||||
|
|
@ -71,7 +67,8 @@ String Ctrl::Name() const {
|
|||
#else
|
||||
String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this);
|
||||
#endif
|
||||
if(IsChild())
|
||||
Ctrl *parent = GetParent();
|
||||
if(parent)
|
||||
s << "(parent " << String(typeid(*parent).name()) << ")";
|
||||
return s;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ private:
|
|||
|
||||
void DestroyWnd();
|
||||
|
||||
void NewTop() { top = new Top; top->owner_window = NULL; }
|
||||
void NewTop() { SetTop(new Top); GetTop()->owner_window = NULL; }
|
||||
void PutForeground();
|
||||
static void MouseEventFB(Ptr<Ctrl> t, int event, Point p, int zdelta);
|
||||
|
||||
|
|
|
|||
|
|
@ -96,44 +96,17 @@ bool Ctrl::DoKeyFB(dword key, int cnt)
|
|||
return b;
|
||||
}
|
||||
|
||||
void Ctrl::SetCaret(int x, int y, int cx, int cy)
|
||||
{
|
||||
GuiLock __;
|
||||
caretx = x;
|
||||
carety = y;
|
||||
caretcx = cx;
|
||||
caretcy = cy;
|
||||
fbCaretTm = msecs();
|
||||
SyncCaret();
|
||||
}
|
||||
|
||||
void Ctrl::SyncCaret()
|
||||
{
|
||||
CursorSync();
|
||||
}
|
||||
|
||||
void Ctrl::CursorSync()
|
||||
{
|
||||
LLOG("@ CursorSync");
|
||||
Point p = GetMousePos() - fbCursorImage.GetHotSpot();
|
||||
Rect cr = Null;
|
||||
if(focusCtrl && (((msecs() - fbCaretTm) / 500) & 1) == 0)
|
||||
cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy)
|
||||
+ focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView();
|
||||
|
||||
if(fbCursorPos != p) {
|
||||
fbCursorPos = p;
|
||||
if(!(VirtualGuiPtr->GetOptions() & GUI_SETMOUSECURSOR))
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
if(cr != fbCaretRect) {
|
||||
fbCaretRect = cr;
|
||||
if(VirtualGuiPtr->GetOptions() & GUI_SETCARET)
|
||||
VirtualGuiPtr->SetCaret(cr);
|
||||
else
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
bool Ctrl::ProcessEvent(bool *quit)
|
||||
|
|
@ -159,6 +132,7 @@ bool Ctrl::ProcessEvents(bool *quit)
|
|||
LLOG("TimerProc invoked at " << msecs());
|
||||
TimerProc(msecs());
|
||||
LLOG("TimerProc elapsed: " << tm);
|
||||
AnimateCaret();
|
||||
SweepMkImageCache();
|
||||
DoPaint();
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ bool Ctrl::invalid;
|
|||
|
||||
Point Ctrl::fbCursorPos = Null;
|
||||
Image Ctrl::fbCursorImage;
|
||||
|
||||
Rect Ctrl::fbCaretRect;
|
||||
int Ctrl::fbCaretTm;
|
||||
bool Ctrl::fbEndSession;
|
||||
|
|
@ -73,9 +74,9 @@ Ctrl *Ctrl::GetOwner()
|
|||
{
|
||||
GuiLock __;
|
||||
int q = FindTopCtrl();
|
||||
if(q > 0 && topctrl[q]->top) {
|
||||
Ctrl *x = topctrl[q]->top->owner_window;
|
||||
LDUMP(Upp::Name(x));
|
||||
Top *top = topctrl[q]->GetTop();
|
||||
if(q > 0 && top) {
|
||||
Ctrl *x = top->owner_window;
|
||||
return dynamic_cast<TopWindowFrame *>(x) ? x->GetOwner() : x;
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -87,36 +88,13 @@ Ctrl *Ctrl::GetActiveCtrl()
|
|||
return focusCtrl ? focusCtrl->GetTopCtrl() : NULL;
|
||||
}
|
||||
|
||||
// Vector<Callback> Ctrl::hotkey;
|
||||
|
||||
int Ctrl::RegisterSystemHotKey(dword key, Function<void ()> cb)
|
||||
{
|
||||
/* ASSERT(key >= K_DELTA);
|
||||
int q = hotkey.GetCount();
|
||||
for(int i = 0; i < hotkey.GetCount(); i++)
|
||||
if(!hotkey[i]) {
|
||||
q = i;
|
||||
break;
|
||||
}
|
||||
hotkey.At(q) = cb;
|
||||
dword mod = 0;
|
||||
if(key & K_ALT)
|
||||
mod |= MOD_ALT;
|
||||
if(key & K_SHIFT)
|
||||
mod |= MOD_SHIFT;
|
||||
if(key & K_CTRL)
|
||||
mod |= MOD_CONTROL;
|
||||
|
||||
return RegisterHotKey(NULL, q, mod, key & 0xffff) ? q : -1;*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Ctrl::UnregisterSystemHotKey(int id)
|
||||
{
|
||||
/* if(id >= 0 && id < hotkey.GetCount()) {
|
||||
UnregisterHotKey(NULL, id);
|
||||
hotkey[id].Clear();
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Ctrl::IsWaitingEvent()
|
||||
|
|
@ -135,30 +113,12 @@ void Ctrl::SyncTopWindows()
|
|||
|
||||
ViewDraw::ViewDraw(Ctrl *ctrl)
|
||||
{
|
||||
/*
|
||||
if(Ctrl::invalid)
|
||||
Ctrl::DoPaint();
|
||||
Ctrl::invalid = false;
|
||||
Ctrl::RemoveCursor();
|
||||
Ctrl::RemoveCaret();
|
||||
Rect r = ctrl->GetScreenView();
|
||||
Ctrl::invalid.Add(r);
|
||||
Ctrl::AddUpdate(r);
|
||||
for(int i = max(ctrl->GetTopCtrl()->FindTopCtrl() + 1, 0); i < Ctrl::topctrl.GetCount(); i++) {
|
||||
Rect rr = Ctrl::topctrl[i]->GetScreenRect();
|
||||
ExcludeClip(rr);
|
||||
Subtract(Ctrl::invalid, rr);
|
||||
}
|
||||
Offset(r.TopLeft());
|
||||
*/
|
||||
}
|
||||
|
||||
ViewDraw::~ViewDraw()
|
||||
{
|
||||
// Ctrl::DoUpdate();
|
||||
}
|
||||
|
||||
|
||||
Rect Ctrl::GetClipBound(const Vector<Rect>& inv, const Rect& r)
|
||||
{
|
||||
Rect ri = Null;
|
||||
|
|
@ -306,18 +266,18 @@ int Ctrl::GetKbdSpeed()
|
|||
|
||||
void Ctrl::DestroyWnd()
|
||||
{
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i]->top && topctrl[i]->top->owner_window == this)
|
||||
for(int i = 0; i < topctrl.GetCount(); i++) {
|
||||
Top *top = topctrl[i]->GetTop();
|
||||
if(top && top->owner_window == this)
|
||||
topctrl[i]->WndDestroy();
|
||||
}
|
||||
int q = FindTopCtrl();
|
||||
if(q >= 0) {
|
||||
Invalidate();
|
||||
topctrl.Remove(q);
|
||||
}
|
||||
if(top) {
|
||||
delete top;
|
||||
top = NULL;
|
||||
}
|
||||
if(top)
|
||||
DeleteTop();
|
||||
isopen = false;
|
||||
TopWindow *win = dynamic_cast<TopWindow *>(this);
|
||||
if(win)
|
||||
|
|
@ -341,8 +301,11 @@ void Ctrl::PutForeground()
|
|||
}
|
||||
Vector< Ptr<Ctrl> > fw;
|
||||
for(int i = 0; i < topctrl.GetCount(); i++)
|
||||
if(topctrl[i] && topctrl[i]->top && topctrl[i]->top->owner_window == this && topctrl[i] != this)
|
||||
fw.Add(topctrl[i]);
|
||||
if(topctrl[i]) {
|
||||
Top *top = topctrl[i]->GetTop();
|
||||
if(top && top->owner_window == this && topctrl[i] != this)
|
||||
fw.Add(topctrl[i]);
|
||||
}
|
||||
for(int i = 0; i < fw.GetCount(); i++)
|
||||
if(fw[i])
|
||||
fw[i]->PutForeground();
|
||||
|
|
@ -355,8 +318,8 @@ void Ctrl::SetWndForeground()
|
|||
if(IsWndForeground())
|
||||
return;
|
||||
Ctrl *to = this;
|
||||
while(to->top && to->top->owner_window)
|
||||
to = to->top->owner_window;
|
||||
while(to->GetTop() && to->GetTop()->owner_window)
|
||||
to = to->GetTop()->owner_window;
|
||||
to->PutForeground();
|
||||
if(this != focusCtrl)
|
||||
ActivateWnd();
|
||||
|
|
@ -445,7 +408,8 @@ void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, boo
|
|||
ASSERT(owner_window->IsOpen());
|
||||
if(owner_window != desktop) {
|
||||
owner_window->SetForeground();
|
||||
top->owner_window = owner_window;
|
||||
if(GetTop())
|
||||
GetTop()->owner_window = owner_window;
|
||||
}
|
||||
}
|
||||
topctrl.Add(this);
|
||||
|
|
@ -496,10 +460,8 @@ void Ctrl::SysEndLoop()
|
|||
|
||||
void Ctrl::DeleteDesktopTop()
|
||||
{
|
||||
if(desktop && desktop->top) {
|
||||
delete desktop->top;
|
||||
desktop->top = NULL;
|
||||
}
|
||||
if(desktop && desktop->GetTop())
|
||||
desktop->DeleteTop();
|
||||
}
|
||||
|
||||
void Ctrl::SetDesktop(Ctrl& q)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ some font system to measure fonts (e.g. DrawGL and plugin/FT`_fontsys).&]
|
|||
[s5;:Upp`:`:VirtualGui`:`:GetOptions`(`): [@(0.0.255) virtual] [_^Upp`:`:dword^ dword]_[* G
|
||||
etOptions]()&]
|
||||
[s2;%% Returns a set of flags describing some aspects of VirtualGui
|
||||
behaviour. Available option flags are:-|&]
|
||||
behaviour. Available option flags are:&]
|
||||
[s2;%% &]
|
||||
[s7;i1120;a17;:Ctrl`:`:CENTER:%% [%-*C@3 GUI`_SETMOUSECURSOR]-|Use the
|
||||
SetMouseCursor() method instead of painting the cursor.&]
|
||||
|
|
|
|||
|
|
@ -679,6 +679,8 @@ void Gdb::SerializeSession(Stream& s)
|
|||
s / version;
|
||||
int n = watches.GetCount();
|
||||
s / n;
|
||||
if(n < 0)
|
||||
s.LoadError();
|
||||
for(int i = 0; i < n; i++) {
|
||||
String w;
|
||||
if(s.IsStoring())
|
||||
|
|
|
|||
|
|
@ -234,6 +234,8 @@ void Pdb::SerializeSession(Stream& s)
|
|||
s / version;
|
||||
int n = watches.GetCount();
|
||||
s / n;
|
||||
if(n < 0)
|
||||
LoadError();
|
||||
for(int i = 0; i < n; i++) {
|
||||
String w;
|
||||
if(s.IsStoring())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue