CtrlLib: SuggestCtrl

git-svn-id: svn://ultimatepp.org/upp/trunk@7378 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-05-15 09:12:28 +00:00
parent 4a5d0fc6be
commit 5f1a91e67a
6 changed files with 261 additions and 1 deletions

View file

@ -44,6 +44,7 @@ class Bar;
#include <CtrlLib/SliderCtrl.h>
#include <CtrlLib/ColumnList.h>
#include <CtrlLib/DateTimeCtrl.h>
#include <CtrlLib/SuggestCtrl.h>
#define LAYOUTFILE <CtrlLib/Ctrl.lay>
#include <CtrlCore/lay.h>

View file

@ -55,6 +55,8 @@ file
Help.cpp,
DateTimeCtrl.h,
DateTimeCtrl.cpp,
SuggestCtrl.h,
SuggestCtrl.cpp,
Bar readonly separator,
Bar.h,
Bar.cpp,

View file

@ -0,0 +1,154 @@
#include "CtrlLib.h"
NAMESPACE_UPP
void SuggestCtrl::CancelMode()
{
Cancel();
}
int SuggestCtrl::IsDelimiter(int c)
{
if(delimiter_filter)
c = (*delimiter_filter)(c);
if(delimiter_char && delimiter_char != c)
c = 0;
return c;
}
WString SuggestCtrl::CF(const WString& src)
{
return compare_filter ? UPP::Filter(src, compare_filter) : src;
}
WString SuggestCtrl::ReadLast(int& h)
{
int l;
GetSelection(l, h);
if(l != h)
return Null;
WString text = GetText();
WString x;
while(--l >= 0 && !IsDelimiter(text[l])) {
h = l;
x.Insert(0, text[l]);
}
return Upp::TrimLeft(x);
}
void SuggestCtrl::Select()
{
if(list.IsCursor()) {
int h;
WString x = ReadLast(h);
int q;
if(GetSelection(q, q))
return;
Remove(h, q - h);
x = list.GetKey();
Insert(h, x);
h += x.GetCount();
SetSelection(h, h);
Cancel();
Action();
}
}
bool SuggestCtrl::Key(dword key, int count)
{
if(list.IsOpen()) {
if(key == K_UP || key == K_PAGEUP || key == K_CTRL_PAGEDOWN)
if(list.IsCursor())
return list.Key(key, count);
else {
list.GoEnd();
return true;
}
if(key == K_DOWN || key == K_PAGEDOWN || key == K_CTRL_PAGEUP)
if(list.IsCursor())
return list.Key(key, count);
else {
list.GoBegin();
return true;
}
}
if(key == K_ENTER && list.IsOpen() && list.IsCursor()) {
Select();
return true;
}
if(key == K_ESCAPE && list.IsOpen()) {
Close();
return true;
}
int cc = IsDelimiter(key);
if(cc)
key = cc;
if(EditString::Key(key, count)) {
if(key >= 32 && key < 65536 || key == K_BACKSPACE || key == K_CTRL_SPACE) {
int h;
WString x = CF(ReadLast(h));
list.Clear();
for(int i = 0; i < data.GetCount(); i++)
if(CF(data[i]).Find(x) >= 0)
list.Add(data[i]);
if(list.GetCount() == 0) {
Cancel();
return true;
}
Rect cr = GetCaretRect(h) + GetScreenView().TopLeft();
Rect wr = GetWorkArea();
int c = droplines * Draw::GetStdFontCy();
Rect r(cr.BottomLeft(), Size(c, c));
r.SetSize(c, c);
if(r.bottom > wr.bottom) {
r.top = cr.top - c;
r.bottom = r.top + c;
}
if(r.right > wr.right) {
r.left = cr.left - c;
r.right = r.left + c;
}
list.SetRect(r);
if(!list.IsOpen())
list.Ctrl::PopUp(GetParent(), false, false, true);
}
else
Cancel();
return true;
}
return false;
}
void SuggestCtrl::Cancel()
{
if(list.IsOpen())
list.Close();
}
void SuggestCtrl::LostFocus()
{
EditField::LostFocus();
Cancel();
}
void SuggestCtrl::GotFocus()
{
EditField::GotFocus();
Move(GetLength());
}
SuggestCtrl::SuggestCtrl()
{
list.AddColumn();
list.NoHeader().NoGrid();
list.SetFrame(BlackFrame());
list.MouseMoveCursor();
list.WhenLeftClick = THISBACK(Select);
list.NoWantFocus();
delimiter_char = 0;
delimiter_filter = NULL;
droplines = 16;
compare_filter = NULL;
}
END_UPP_NAMESPACE

View file

@ -0,0 +1,36 @@
class SuggestCtrl : public EditString {
virtual bool Key(dword key, int count);
virtual void CancelMode();
virtual void LostFocus();
virtual void GotFocus();
private:
Vector<WString> data;
ArrayCtrl list;
int droplines;
int delimiter_char;
int (*delimiter_filter)(int c);
int (*compare_filter)(int c);
void Cancel();
void Select();
WString ReadLast(int& h);
int IsDelimiter(int c);
WString CF(const WString& src);
typedef SuggestCtrl CLASSNAME;
public:
void ClearList() { data.Clear(); }
void Add(const WString& s) { data.Add(s); }
void Add(const String& s) { data.Add(s.ToWString()); }
void Pick(Vector<WString> rval_ list) { data = pick(list); }
SuggestCtrl& SetDropLines(int n) { droplines = n; return *this; }
SuggestCtrl& Delimiter(int chr) { delimiter_char = chr; return *this; }
SuggestCtrl& Delimiter(int (*filter)(int c)) { delimiter_filter = filter; return *this; }
SuggestCtrl& CompareFilter(int (*filter)(int c)) { compare_filter = filter; return *this; }
SuggestCtrl();
};

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,7 @@
#ifndef _plugin_jpg_icpp_init_stub
#define _plugin_jpg_icpp_init_stub
#include "Draw/init"
#define BLITZ_INDEX__ Fd014d588c5c3282b5385cf46a1e5c56c
#define BLITZ_INDEX__ F227b3ee1134af92a2493f791a66e2afe
#include "jpgreg.icpp"
#undef BLITZ_INDEX__
#endif