mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
205 lines
3.8 KiB
C++
205 lines
3.8 KiB
C++
#include "CtrlLib.h"
|
|
|
|
namespace Upp {
|
|
|
|
DropChoice::DropChoice() {
|
|
always_drop = hide_drop = false;
|
|
AddButton().Main() <<= THISBACK(Drop);
|
|
NoDisplay();
|
|
list.WhenSelect = [this] { Select(); };
|
|
dropfocus = true;
|
|
EnableDrop(false);
|
|
dropwidth = 0;
|
|
appending = false;
|
|
updownkeys = true;
|
|
rodrop = false;
|
|
}
|
|
|
|
void DropChoice::AddTo(Ctrl& _owner)
|
|
{
|
|
MultiButtonFrame::AddTo(_owner);
|
|
owner = &_owner;
|
|
|
|
if(auto *ef = dynamic_cast<EditField *>(owner))
|
|
ef->WhenPaper = [this](Color c) { MultiButtonFrame::SetPaper(c); };
|
|
}
|
|
|
|
void DropChoice::EnableDrop(bool b)
|
|
{
|
|
MainButton().Enable(b);
|
|
if(hide_drop)
|
|
MainButton().Show(b);
|
|
}
|
|
|
|
void DropChoice::PseudoPush()
|
|
{
|
|
MultiButton::PseudoPush(0);
|
|
}
|
|
|
|
void DropChoice::Drop() {
|
|
if(!owner || owner->IsReadOnly() && !rodrop || list.GetCount() == 0 && !WhenDrop) return;
|
|
WhenDrop();
|
|
if(dropfocus)
|
|
owner->SetWantFocus();
|
|
int i = list.Find(owner->GetData());
|
|
if(i >= 0)
|
|
list.SetCursor(i);
|
|
else
|
|
if(list.GetCount() > 0)
|
|
list.SetCursor(0);
|
|
list.PopUp(owner,dropwidth);
|
|
}
|
|
|
|
void DropChoice::Select() {
|
|
if(!owner || owner->IsReadOnly() && !rodrop) return;
|
|
WhenSelect();
|
|
}
|
|
|
|
Value DropChoice::Get() const {
|
|
if(!owner || owner->IsReadOnly() && !rodrop) return Value();
|
|
int c = list.GetCursor();
|
|
if(c < 0) return Value();
|
|
return list.Get(c);
|
|
}
|
|
|
|
int DropChoice::GetIndex() const
|
|
{
|
|
if(!owner || owner->IsReadOnly() && !rodrop) return -1;
|
|
return list.GetCursor();
|
|
}
|
|
|
|
bool DropChoice::DataSelect(Ctrl& owner, DropChoice& drop, const String& appends) {
|
|
Value g = drop.Get();
|
|
if(g.IsVoid()) return false;
|
|
Value s = owner.GetData();
|
|
if(!appends.IsVoid()) {
|
|
String txt = s;
|
|
if(!txt.IsEmpty()) txt.Cat(appends);
|
|
txt.Cat((String)g);
|
|
s = txt;
|
|
}
|
|
else
|
|
s = g;
|
|
owner.SetData(s);
|
|
owner.WhenAction();
|
|
return true;
|
|
}
|
|
|
|
void DropChoice::DoWheel(int zdelta)
|
|
{
|
|
if(!appending)
|
|
DoKey(zdelta < 0 ? K_UP : K_DOWN);
|
|
}
|
|
|
|
bool DropChoice::DoKey(dword key) {
|
|
if(owner && !owner->IsReadOnly() && list.GetCount()) {
|
|
int q = list.GetCursor();
|
|
switch(key) {
|
|
case K_ALT_DOWN:
|
|
PseudoPush();
|
|
return true;
|
|
case K_DOWN:
|
|
if(!updownkeys)
|
|
return false;
|
|
if(appending)
|
|
PseudoPush();
|
|
else {
|
|
list.SetCursor(q <= 0 ? list.GetCount() - 1 : q - 1);
|
|
Select();
|
|
}
|
|
return true;
|
|
case K_UP:
|
|
if(!updownkeys)
|
|
return false;
|
|
if(appending)
|
|
PseudoPush();
|
|
else {
|
|
list.SetCursor(q < 0 || q >= list.GetCount() - 1 ? 0 : q + 1);
|
|
Select();
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void DropChoice::Add(const Value& s)
|
|
{
|
|
list.Add(s);
|
|
EnableDrop(true);
|
|
}
|
|
|
|
void DropChoice::FindAdd(const Value& s)
|
|
{
|
|
if (list.Find(s) < 0)
|
|
list.Add(s);
|
|
EnableDrop(true);
|
|
}
|
|
|
|
void DropChoice::Remove(int i)
|
|
{
|
|
list.Remove(i);
|
|
EnableDrop(list.GetCount());
|
|
}
|
|
|
|
void DropChoice::Clear() {
|
|
list.Clear();
|
|
EnableDrop(always_drop);
|
|
}
|
|
|
|
void DropChoice::Serialize(Stream& s) {
|
|
// This is unfortunately a fix for bug and its consequences in existing .cfg files...
|
|
int version = 0x01;
|
|
s / version;
|
|
if(version < 0x01) {
|
|
int n = list.GetCount();
|
|
s / n;
|
|
Value v;
|
|
if(s.IsLoading())
|
|
for(int i = 0; i < n; i++)
|
|
s % v;
|
|
}
|
|
}
|
|
|
|
void DropChoice::SerializeList(Stream& s) {
|
|
int version = 0x00;
|
|
int n = list.GetCount();
|
|
s / version / n;
|
|
Value v;
|
|
if(s.IsLoading()) {
|
|
Clear();
|
|
for(int i = 0; i < n; i++) {
|
|
s % v;
|
|
Add(v);
|
|
}
|
|
}
|
|
else
|
|
for(int i = 0; i < n; i++) {
|
|
v = list.Get(i);
|
|
s % v;
|
|
}
|
|
EnableDrop(list.GetCount() || always_drop);
|
|
}
|
|
|
|
void DropChoice::AddHistory(const Value& v, int max) {
|
|
if(IsNull(v)) return;
|
|
for(int i = 0; i < list.GetCount(); i++)
|
|
if(list.Get(i) == v) {
|
|
list.Remove(i);
|
|
break;
|
|
}
|
|
list.Insert(0, v);
|
|
if(list.GetCount() > max)
|
|
list.SetCount(max);
|
|
EnableDrop(list.GetCount() || always_drop);
|
|
list.SetCursor(-1);
|
|
}
|
|
|
|
DropChoice& DropChoice::AlwaysDrop(bool e)
|
|
{
|
|
always_drop = e;
|
|
EnableDrop(list.GetCount() || always_drop);
|
|
return *this;
|
|
}
|
|
|
|
}
|