From 285719ebb38c25a040887f075f14ddc255647ad0 Mon Sep 17 00:00:00 2001 From: cxl Date: Thu, 19 Apr 2018 14:51:06 +0000 Subject: [PATCH] .SlaveGui git-svn-id: svn://ultimatepp.org/upp/trunk@11899 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- rainbow/SDL20GL/Wnd.cpp | 4 +- rainbow/SlaveGui/After.h | 51 + rainbow/SlaveGui/ChSysInit.cpp | 21 + rainbow/SlaveGui/Clip.cpp | 238 ++ rainbow/SlaveGui/Ctrl.cpp | 81 + rainbow/SlaveGui/Ctrl.h | 74 + rainbow/SlaveGui/Cursor.cpp | 81 + rainbow/SlaveGui/DnD.cpp | 150 ++ rainbow/SlaveGui/DrawDragRect.cpp | 92 + rainbow/SlaveGui/Event.cpp | 424 ++++ rainbow/SlaveGui/FB.iml | 63 + rainbow/SlaveGui/Gui.h | 358 +++ rainbow/SlaveGui/Image.cpp | 47 + rainbow/SlaveGui/Keys.h | 123 + rainbow/SlaveGui/Local.h | 65 + rainbow/SlaveGui/SDL.cpp | 81 + rainbow/SlaveGui/SlaveGui.h | 118 + rainbow/SlaveGui/SlaveGui.upp | 34 + rainbow/SlaveGui/Top.cpp | 149 ++ rainbow/SlaveGui/Top.h | 16 + rainbow/SlaveGui/TopFrame.cpp | 236 ++ rainbow/SlaveGui/Window.cpp | 53 + rainbow/SlaveGui/Wnd.cpp | 540 ++++ rainbow/SlaveGuiUword/SlaveGuiUword.upp | 14 + rainbow/SlaveGuiUword/help.txt | 20 + rainbow/SlaveGuiUword/main.cpp | 258 ++ rainbow/SlaveGuiUword/test.cpp | 5 + rainbow/SlaveGuiUword/test.qtf | 2998 +++++++++++++++++++++++ rainbow/guiplatform.h | 6 + 29 files changed, 6398 insertions(+), 2 deletions(-) create mode 100644 rainbow/SlaveGui/After.h create mode 100644 rainbow/SlaveGui/ChSysInit.cpp create mode 100644 rainbow/SlaveGui/Clip.cpp create mode 100644 rainbow/SlaveGui/Ctrl.cpp create mode 100644 rainbow/SlaveGui/Ctrl.h create mode 100644 rainbow/SlaveGui/Cursor.cpp create mode 100644 rainbow/SlaveGui/DnD.cpp create mode 100644 rainbow/SlaveGui/DrawDragRect.cpp create mode 100644 rainbow/SlaveGui/Event.cpp create mode 100644 rainbow/SlaveGui/FB.iml create mode 100644 rainbow/SlaveGui/Gui.h create mode 100644 rainbow/SlaveGui/Image.cpp create mode 100644 rainbow/SlaveGui/Keys.h create mode 100644 rainbow/SlaveGui/Local.h create mode 100644 rainbow/SlaveGui/SDL.cpp create mode 100644 rainbow/SlaveGui/SlaveGui.h create mode 100644 rainbow/SlaveGui/SlaveGui.upp create mode 100644 rainbow/SlaveGui/Top.cpp create mode 100644 rainbow/SlaveGui/Top.h create mode 100644 rainbow/SlaveGui/TopFrame.cpp create mode 100644 rainbow/SlaveGui/Window.cpp create mode 100644 rainbow/SlaveGui/Wnd.cpp create mode 100644 rainbow/SlaveGuiUword/SlaveGuiUword.upp create mode 100644 rainbow/SlaveGuiUword/help.txt create mode 100644 rainbow/SlaveGuiUword/main.cpp create mode 100644 rainbow/SlaveGuiUword/test.cpp create mode 100644 rainbow/SlaveGuiUword/test.qtf diff --git a/rainbow/SDL20GL/Wnd.cpp b/rainbow/SDL20GL/Wnd.cpp index 81792d3ed..965ca8312 100644 --- a/rainbow/SDL20GL/Wnd.cpp +++ b/rainbow/SDL20GL/Wnd.cpp @@ -38,9 +38,9 @@ void Ctrl::InitFB() Ctrl::GlobalBackBuffer(); Ctrl::InitTimer(); -#ifdef PLATFORM_POSIX +// #ifdef PLATFORM_POSIX SetStdFont(ScreenSans(12)); //FIXME general handling -#endif +// #endif ChStdSkin(); static StaticRect x; diff --git a/rainbow/SlaveGui/After.h b/rainbow/SlaveGui/After.h new file mode 100644 index 000000000..8f241c17e --- /dev/null +++ b/rainbow/SlaveGui/After.h @@ -0,0 +1,51 @@ +class ViewDraw : public SystemDraw { +public: + ViewDraw(Ctrl *ctrl); + ~ViewDraw(); +}; + + +/* +class ViewDraw : public SystemDraw { + Vector dummy; +public: + ViewDraw(Ctrl *) : SystemDraw(Ctrl::framebuffer, dummy) { dummy.Add(Rect(10, 10, 100, 100)); } +}; +*/ +class DHCtrl : Ctrl {}; + +void FBInit(); +void FBDeInit(); + +#ifdef PLATFORM_WIN32 +#define GUI_APP_MAIN \ +void GuiMainFn_(); \ +\ +extern "C" int main(int argc, char *argv[]) { \ + UPP::AppInit__(argc, (const char **)argv); \ + FBInit(); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + FBDeInit(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() + +#endif + +#ifdef PLATFORM_POSIX +#define GUI_APP_MAIN \ +void GuiMainFn_(); \ +\ +extern "C" int main(int argc, const char **argv, const char **envptr) { \ + UPP::AppInit__(argc, argv, envptr); \ + FBInit(); \ + GuiMainFn_(); \ + UPP::Ctrl::CloseTopCtrls(); \ + FBDeInit(); \ + return UPP::GetExitCode(); \ +} \ +\ +void GuiMainFn_() +#endif diff --git a/rainbow/SlaveGui/ChSysInit.cpp b/rainbow/SlaveGui/ChSysInit.cpp new file mode 100644 index 000000000..bae67d35e --- /dev/null +++ b/rainbow/SlaveGui/ChSysInit.cpp @@ -0,0 +1,21 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +void ChSysInit() +{ + CtrlImg::Reset(); + CtrlsImg::Reset(); + ChReset(); +} + +void ChHostSkin() +{ + ChSysInit(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Clip.cpp b/rainbow/SlaveGui/Clip.cpp new file mode 100644 index 000000000..9c70c4b0f --- /dev/null +++ b/rainbow/SlaveGui/Clip.cpp @@ -0,0 +1,238 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +static VectorMap fbClipboard; + +void ClearClipboard() +{ + GuiLock __; + fbClipboard.Clear(); +} + +void AppendClipboard(const char *format, const Value& data, String (*render)(const Value&)) +{ + GuiLock __; + ClipData& cd = fbClipboard.GetAdd(format); + cd.data = data; + cd.render = render; +} + +static String sRawRender(const Value& v) +{ + return v; +} + +void AppendClipboard(const char *format, const String& data) +{ + GuiLock __; + AppendClipboard(format, data, sRawRender); +} + +void AppendClipboard(const char *format, const byte *data, int length) +{ + GuiLock __; + AppendClipboard(format, String(data, length)); +} + +String ReadClipboard(const char *format) +{ + GuiLock __; + int q = fbClipboard.Find(format); + return q >= 0 ? (*fbClipboard[q].render)(fbClipboard[q].data) : String(); +} + +void AppendClipboardText(const String& s) +{ + AppendClipboard("text", ToSystemCharset(s)); +} + +void AppendClipboardUnicodeText(const WString& s) +{ + AppendClipboard("wtext", (byte *)~s, 2 * s.GetLength()); +} + +const char *ClipFmtsText() +{ + return "wtext;text"; +} + +String GetString(PasteClip& clip) +{ + GuiLock __; + if(clip.Accept("wtext")) { + String s = ~clip; + return WString((const wchar *)~s, wstrlen((const wchar *)~s)).ToString(); + } + if(clip.IsAvailable("text")) + return ~clip; + return Null; +} + +WString GetWString(PasteClip& clip) +{ + GuiLock __; + if(clip.Accept("wtext")) { + String s = ~clip; + return WString((const wchar *)~s, wstrlen((const wchar *)~s)); + } + if(clip.IsAvailable("text")) + return (~clip).ToWString(); + return Null; +} + + +bool AcceptText(PasteClip& clip) +{ + return clip.Accept(ClipFmtsText()); +} + +static String sText(const Value& data) +{ + return data; +} + +static String sWText(const Value& data) +{ + return Unicode__(WString(data)); +} + +void Append(VectorMap& data, const String& text) +{ + data.GetAdd("text", ClipData(text, sText)); + data.GetAdd("wtext", ClipData(text, sWText)); +} + +void Append(VectorMap& data, const WString& text) +{ + data.GetAdd("text", ClipData(text, sText)); + data.GetAdd("wtext", ClipData(text, sWText)); +} + +String GetTextClip(const WString& text, const String& fmt) +{ + if(fmt == "text") + return text.ToString(); + if(fmt == "wtext") + return Unicode__(text); + return Null; +} + +String GetTextClip(const String& text, const String& fmt) +{ + if(fmt == "text") + return text; + if(fmt == "wtext") + return Unicode__(text.ToWString()); + return Null; +} + +String ReadClipboardText() +{ + String w = ReadClipboard("text"); + return w.GetCount() ? w : ReadClipboardUnicodeText().ToString(); +} + +WString ReadClipboardUnicodeText() +{ + String w = ReadClipboard("wtext"); + if(w.GetCount()) + return WString((const wchar *)~w, w.GetLength() / 2); + return ReadClipboard("text").ToWString(); +} + +bool IsClipboardAvailable(const char *id) +{ + return fbClipboard.Find(id) >= 0; +} + +bool IsClipboardAvailableText() +{ + return IsClipboardAvailable("text") || IsClipboardAvailable("wtext"); +} + +const char *ClipFmtsImage() +{ + static const char *q; + ONCELOCK { + static String s = "dib;" + ClipFmt(); + q = s; + } + return q; +} + +bool AcceptImage(PasteClip& clip) +{ + GuiLock __; + return clip.Accept(ClipFmtsImage()); +} + +Image GetImage(PasteClip& clip) +{ + GuiLock __; + Image m; + if(Accept(clip)) { + LoadFromString(m, ~clip); + if(!m.IsEmpty()) + return m; + } + return Null; +} + +Image ReadClipboardImage() +{ + GuiLock __; + PasteClip d = Ctrl::Clipboard(); + return GetImage(d); +} + +String sImage(const Value& image) +{ + Image img = image; + return StoreAsString(const_cast(img)); +} + +String GetImageClip(const Image& img, const String& fmt) +{ + GuiLock __; + if(img.IsEmpty()) return Null; + if(fmt == ClipFmt()) + return sImage(img); + return Null; +} + +void AppendClipboardImage(const Image& img) +{ + GuiLock __; + if(img.IsEmpty()) return; + AppendClipboard(ClipFmt(), img, sImage); +} + +bool AcceptFiles(PasteClip& clip) +{ + if(clip.Accept("files")) { + clip.SetAction(DND_COPY); + return true; + } + return false; +} + +bool IsAvailableFiles(PasteClip& clip) +{ + return clip.IsAvailable("files"); +} + +Vector GetFiles(PasteClip& clip) +{ + GuiLock __; + Vector f; + return f; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Ctrl.cpp b/rainbow/SlaveGui/Ctrl.cpp new file mode 100644 index 000000000..25020af61 --- /dev/null +++ b/rainbow/SlaveGui/Ctrl.cpp @@ -0,0 +1,81 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +#define LLOG(x) // DLOG(x) + +NAMESPACE_UPP + +void Ctrl::GuiPlatformConstruct() +{ +} + +void Ctrl::GuiPlatformRemove() +{ +} + +void Ctrl::GuiPlatformGetTopRect(Rect& r) const +{ +} + +bool Ctrl::GuiPlatformRefreshFrameSpecial(const Rect& r) +{ + return false; +} + +bool Ctrl::GuiPlatformSetFullRefreshSpecial() +{ + return false; +} + +void Ctrl::PaintCaret(SystemDraw& w) +{ +} + +String GuiPlatformGetKeyDesc(dword key) +{ + return Null; +} + +void Ctrl::GuiPlatformSelection(PasteClip&) +{ +} + +void GuiPlatformAdjustDragImage(ImageBuffer&) +{ +} + +bool GuiPlatformHasSizeGrip() +{ + return true; +} + +void GuiPlatformGripResize(TopWindow *q) +{ + q->GripResize(); +} + +Color GuiPlatformGetScreenPixel(int x, int y) +{ + return Null; +} + +void GuiPlatformAfterMenuPopUp() +{ +} + +String Ctrl::Name() const { + GuiLock __; +#ifdef CPU_64 + String s = String(typeid(*this).name()) + " : 0x" + FormatIntHex(this); +#else + String s = String(typeid(*this).name()) + " : " + Format("0x%x", (int) this); +#endif + if(IsChild()) + s << "(parent " << String(typeid(*parent).name()) << ")"; + return s; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Ctrl.h b/rainbow/SlaveGui/Ctrl.h new file mode 100644 index 000000000..8de4ee9de --- /dev/null +++ b/rainbow/SlaveGui/Ctrl.h @@ -0,0 +1,74 @@ +//$ class Ctrl { +private: + static Ptr desktop; + static Vector topctrl; + static bool invalid; + + static Point fbCursorPos; + static Image fbCursorImage; + static bool sdlMouseIsIn; + + static Rect fbCaretRect; + static int fbCaretTm; + + static bool fbEndSession; + static int64 fbEventLoop; + static int64 fbEndSessionLoop; + + static void CursorSync(); + + int FindTopCtrl() const; + static Rect GetClipBound(const Vector& inv, const Rect& r); + static void DoPaint(); + static void SyncTopWindows(); + +// static void AddInvalid(const Rect& rect); + + void DestroyWnd(); + + void NewTop() { top = new Top; top->owner_window = NULL; } + void PutForeground(); + static void MouseEventFB(Ptr t, int event, Point p, int zdelta); + + static void DrawLine(const Vector& clip, int x, int y, int cx, int cy, bool horz, + const byte *pattern, int animation); + static void DragRectDraw0(const Vector& clip, const Rect& rect, int n, + const byte *pattern, int animation); + + friend struct PaintProxy__; + friend class TopWindowFrame; + friend class SystemDraw; + friend struct DnDLoop; + + void SetOpen(bool b) { isopen = b; } + +protected: + static int PaintLock; + +public: + static void DoMouseFB(int event, Point p, int zdelta = 0); + static bool DoKeyFB(dword key, int cnt); + + static void InitFB(); + static void ExitFB(); + static void EndSession(); + + static void SetDesktop(Ctrl& q); + static Ctrl *GetDesktop() { return desktop; } + static void SetDesktopSize(Size sz); + + static void Invalidate() { invalid = true; } + + void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation); + + static Ctrl *FindMouseTopCtrl(); + + static void PaintScene(SystemDraw& draw); + static void PaintCaretCursor(SystemDraw& draw); + + static bool SystemCursor; + + enum { DRAWDRAGRECT_SCREEN = 0x8000 }; + +//$ }; diff --git a/rainbow/SlaveGui/Cursor.cpp b/rainbow/SlaveGui/Cursor.cpp new file mode 100644 index 000000000..ccd962b77 --- /dev/null +++ b/rainbow/SlaveGui/Cursor.cpp @@ -0,0 +1,81 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) + +void Ctrl::SetMouseCursor(const Image& image) +{ + GuiLock __; + SlaveGuiPtr->SetMouseCursor(image); +} + +#if 0 +struct RectSDL { + SDL_Rect sr; + + operator SDL_Rect *() { return &sr; } + + RectSDL(const Rect& r) + { + sr.x = r.left; + sr.y = r.top; + sr.w = r.GetWidth(); + sr.h = r.GetHeight(); + } +}; + +SDL_Texture *SDLTextureFromImage(SDL_Renderer *renderer, const Image& m) +{ + Size isz = m.GetSize(); + SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STATIC, isz.cx, isz.cy); + if(texture) { + SDL_UpdateTexture(texture, RectSDL(isz), ~m, isz.cx * sizeof(RGBA)); + SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND); + } + return texture; +} + +SDL_Cursor *sdl_cursor; +SDL_Surface *sdl_cursor_surface; +Buffer data; + + if(image.GetSerialId() != fbCursorImage.GetSerialId()) { + fbCursorImage = image; + fbCursorPos = Null; + SDL_ShowCursor(SystemCursor); + if(SystemCursor) { + if(sdl_cursor) + SDL_FreeCursor(sdl_cursor); + if(sdl_cursor_surface) + SDL_FreeSurface(sdl_cursor_surface); + + int64 a = image.GetAuxData(); + if(a) + sdl_cursor = SDL_CreateSystemCursor(SDL_SystemCursor(a - 1)); + else { + sdl_cursor = NULL; + data.Alloc(image.GetLength()); + Copy(data, image, image.GetLength()); + sdl_cursor_surface = SDL_CreateRGBSurfaceFrom(~data, image.GetWidth(), image.GetHeight(), + 32, sizeof(RGBA) * image.GetWidth(), + 0xff0000, 0xff00, 0xff, 0xff000000); + Point h = image.GetHotSpot(); + if(sdl_cursor_surface) + sdl_cursor = SDL_CreateColorCursor(sdl_cursor_surface, h.x, h.y); + } + if(sdl_cursor) + SDL_SetCursor(sdl_cursor); + } + } +} + +#endif + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/DnD.cpp b/rainbow/SlaveGui/DnD.cpp new file mode 100644 index 000000000..18ef912e6 --- /dev/null +++ b/rainbow/SlaveGui/DnD.cpp @@ -0,0 +1,150 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) // DLOG(x) + +// -------------------------------------------------------------------------------------------- + +Ptr sDnDSource; + +Ctrl * Ctrl::GetDragAndDropSource() +{ + return sDnDSource; +} + +struct DnDLoop : LocalLoop { + const VectorMap *data; + Vector fmts; + + Image move, copy, reject; + Ptr target; + int action; + byte actions; + + void Sync(); + String GetData(const String& f); + void DnD(bool paste); + + virtual void LeftUp(Point, dword); + virtual bool Key(dword, int); + virtual void MouseMove(Point p, dword); + virtual Image CursorImage(Point, dword); +}; + +Ptr dndloop; + +bool PasteClip::IsAvailable(const char *fmt) const +{ + GuiLock __; + return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0 + : IsClipboardAvailable(fmt); +} + +String DnDLoop::GetData(const String& f) +{ + GuiLock __; + int i = data->Find(f); + String d; + if(i >= 0) + d = (*data)[i].Render(); + else + if(sDnDSource) + d = sDnDSource->GetDropData(f); + return d; +} + +String PasteClip::Get(const char *fmt) const +{ + return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt); +} + +void PasteClip::GuiPlatformConstruct() +{ + dnd = false; +} + +void DnDLoop::DnD(bool paste) +{ + PasteClip d; + d.paste = paste; + d.accepted = false; + d.allowed = (byte)actions; + d.action = GetCtrl() ? DND_COPY : DND_MOVE; + d.dnd = true; + if(target) + target->DnD(GetMousePos(), d); + action = d.IsAccepted() ? d.GetAction() : DND_NONE; +} + +void DnDLoop::Sync() +{ + GuiLock __; + Ptr t = FindMouseTopCtrl(); + if(t != target) + if(target) + target->DnDLeave(); + target = t; + DnD(false); +} + +void DnDLoop::LeftUp(Point, dword) +{ + GuiLock __; + LLOG("DnDLoop::LeftUp"); + DnD(true); + EndLoop(); +} + +void DnDLoop::MouseMove(Point p, dword) +{ + GuiLock __; + LLOG("DnDLoop::MouseMove"); + Sync(); +} + +bool DnDLoop::Key(dword, int) +{ + GuiLock __; + LLOG("DnDLoop::Key"); + Sync(); + return false; +} + +Image DnDLoop::CursorImage(Point, dword) +{ + GuiLock __; + return action == DND_MOVE ? move : action == DND_COPY ? copy : reject; +} + +int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, + const VectorMap& data) +{ + GuiLock __; + DnDLoop d; + d.actions = (byte)actions; + d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample); + if(actions & DND_COPY) + d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample); + if(actions & DND_MOVE) + d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample); + d.SetMaster(*this); + d.data = &data; + d.action = DND_NONE; + d.fmts = Split(fmts, ';'); + dndloop = &d; + sDnDSource = this; + d.Run(); + sDnDSource = NULL; + SyncCaret(); + LLOG("DoDragAndDrop finished"); + return d.action; +} + +void Ctrl::SetSelectionSource(const char *fmts) {} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/DrawDragRect.cpp b/rainbow/SlaveGui/DrawDragRect.cpp new file mode 100644 index 000000000..a1ce72c25 --- /dev/null +++ b/rainbow/SlaveGui/DrawDragRect.cpp @@ -0,0 +1,92 @@ +#include "Local.h" + +NAMESPACE_UPP + +struct DrawDragRectInfo { + Rect rect1, rect2, clip; + int n; + int type; + int animation; +}; + +void DrawDragLine(SystemDraw& w, bool horz, int x, int y, int len, int n, const int *pattern, int animation) +{ + if(len <= 0) + return; + if(horz) + w.Clip(x, y, len, n); + else + w.Clip(x, y, n, len); + + (horz ? x : y) -= animation; + len += animation; + bool ch = false; + while(len > 0) { + int segment = pattern[ch]; + int d = segment + pattern[2]; + if(horz) { + w.DrawRect(x, y, segment, n, InvertColor()); + x += d; + } + else { + w.DrawRect(x, y, n, segment, InvertColor()); + y += d; + } + len -= d; + ch = !ch; + } + w.End(); +} + +void DrawDragFrame(SystemDraw& w, const Rect& r, int n, const int *pattern, int animation) +{ + DrawDragLine(w, true, r.left, r.top, r.GetWidth(), n, pattern, animation); + DrawDragLine(w, false, r.left, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); + DrawDragLine(w, false, r.right - n, r.top + n, r.GetHeight() - 2 * n, n, pattern, animation); + DrawDragLine(w, true, r.left, r.bottom - n, r.GetWidth(), n, pattern, animation); +} + +void DrawDragRect(Ctrl& q, const DrawDragRectInfo& f) +{ + SystemDraw w; + Ctrl::PaintScene(w); + w.Clip(f.clip); + static int dashes[3][3] = { + { 32, 32, 0 }, + { 1, 1, 1 }, + { 5, 1, 2 }, + }; + const int *dash = dashes[minmax(f.type, 0, 2)]; + DrawDragFrame(w, f.rect1, f.n, dash, f.animation); + DrawDragFrame(w, f.rect2, f.n, dash, f.animation); + w.End(); + Ctrl::PaintCaretCursor(w); + SDL_GL_SwapWindow(screen.win); +} + +void DrawDragRect(Ctrl& q, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, int type, int animation) +{ + Ctrl *top = q.GetTopCtrl(); + if(top) { + Point off = q.GetScreenView().TopLeft(); + DrawDragRectInfo f; + f.rect1 = rect1.Offseted(off); + f.rect2 = rect2.Offseted(off); + f.clip = (clip & q.GetSize()).Offseted(off); + f.n = n; + f.type = type; + f.animation = animation; + DrawDragRect(*top, f); + } +} + +void FinishDragRect(Ctrl& q) +{ + SystemDraw w; + Ctrl::PaintScene(w); + Ctrl::PaintCaretCursor(w); + SDL_GL_SwapWindow(screen.win); +} + +END_UPP_NAMESPACE diff --git a/rainbow/SlaveGui/Event.cpp b/rainbow/SlaveGui/Event.cpp new file mode 100644 index 000000000..ecc1a6b9a --- /dev/null +++ b/rainbow/SlaveGui/Event.cpp @@ -0,0 +1,424 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) + +static Point fbmousepos; + +int SDLwidth; +int SDLheight; + +Point GetMousePos() { + return fbmousepos; +} + +dword mouseb = 0; +dword modkeys = 0; + +enum KM { + KM_NONE = 0x00, + + KM_LSHIFT= 0x01, + KM_RSHIFT= 0x02, + KM_LCTRL = 0x04, + KM_RCTRL = 0x08, + KM_LALT = 0x10, + KM_RALT = 0x20, + + KM_CAPS = 0x40, + KM_NUM = 0x80, + + KM_CTRL = KM_LCTRL | KM_RCTRL, + KM_SHIFT = KM_LSHIFT | KM_RSHIFT, + KM_ALT = KM_LALT | KM_RALT, +}; + +bool GetMouseLeft() { return mouseb & (1<<0); } +bool GetMouseRight() { return mouseb & (1<<1); } +bool GetMouseMiddle() { return mouseb & (1<<2); } +bool GetShift() { return modkeys & KM_SHIFT; } +bool GetCtrl() { return modkeys & KM_CTRL; } +bool GetAlt() { return modkeys & KM_ALT; } +bool GetCapsLock() { return modkeys & KM_CAPS; } + +#if 0 + +dword fbKEYtoK(dword chr) { + if(chr == SDLK_TAB) + chr = K_TAB; + else + if(chr == SDLK_SPACE) + chr = K_SPACE; + else + if(chr == SDLK_RETURN) + chr = K_RETURN; + else + chr = chr + K_DELTA; + if(chr == K_ALT_KEY || chr == K_CTRL_KEY || chr == K_SHIFT_KEY) + return chr; + if(GetCtrl()) chr |= K_CTRL; + if(GetAlt()) chr |= K_ALT; + if(GetShift()) chr |= K_SHIFT; + return chr; +} + +dword lastbdowntime[8] = {0}; +dword isdblclick[8] = {0}; + +void Ctrl::HandleSDLEvent(SDL_Event* event) +{ + LLOG("HandleSDLEvent " << event->type); + SDL_Event next_event; + dword keycode; + switch(event->type) { +// case SDL_ACTIVEEVENT: //SDL_ActiveEvent +// break; + case SDL_TEXTINPUT: { + //send respective keyup things as char events as well + WString text = FromUtf8(event->text.text); + for(int i = 0; i < text.GetCount(); i++) { + int c = text[i]; + if(c != 127) + Ctrl::DoKeyFB(c, 1); + } + break; + } + case SDL_KEYDOWN: + switch(event->key.keysym.sym) { + case SDLK_LSHIFT: modkeys |= KM_LSHIFT; break; + case SDLK_RSHIFT: modkeys |= KM_RSHIFT; break; + case SDLK_LCTRL: modkeys |= KM_LCTRL; break; + case SDLK_RCTRL: modkeys |= KM_RCTRL; break; + case SDLK_LALT: modkeys |= KM_LALT; break; + case SDLK_RALT: modkeys |= KM_RALT; break; + } + + keycode = fbKEYtoK((dword)event->key.keysym.sym); + + if(keycode != K_SPACE) { //dont send space on keydown + static int repeat_count; + SDL_PumpEvents(); + if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_KEYDOWN, SDL_KEYDOWN) && + next_event.key.keysym.sym == event->key.keysym.sym) { + repeat_count++; // Keyboard repeat compression + break; + } + Ctrl::DoKeyFB(keycode, 1 + repeat_count); + repeat_count = 0; + } + break; + case SDL_KEYUP: //SDL_KeyboardEvent + switch(event->key.keysym.sym) { + case SDLK_LSHIFT: modkeys &= ~KM_LSHIFT; break; + case SDLK_RSHIFT: modkeys &= ~KM_RSHIFT; break; + case SDLK_LCTRL: modkeys &= ~KM_LCTRL; break; + case SDLK_RCTRL: modkeys &= ~KM_RCTRL; break; + case SDLK_LALT: modkeys &= ~KM_LALT; break; + case SDLK_RALT: modkeys &= ~KM_RALT; break; + } + + Ctrl::DoKeyFB(fbKEYtoK((dword)event->key.keysym.sym) | K_KEYUP, 1); + break; + case SDL_MOUSEMOTION: + SDL_PumpEvents(); + if(SDL_PeepEvents(&next_event, 1, SDL_PEEKEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION) > 0) + break; // MouseMove compression + Ctrl::DoMouseFB(Ctrl::MOUSEMOVE, Point(event->motion.x, event->motion.y)); + break; + case SDL_MOUSEWHEEL: + Ctrl::DoMouseFB(Ctrl::MOUSEWHEEL, GetMousePos(), sgn(event->wheel.y) * 120); + break; + case SDL_MOUSEBUTTONDOWN: { + Point p(event->button.x, event->button.y); + int bi = event->button.button; + dword ct = SDL_GetTicks(); + if(isdblclick[bi] && (abs(int(ct) - int(lastbdowntime[bi])) < 400)) + { + switch(bi) + { + case SDL_BUTTON_LEFT: Ctrl::DoMouseFB(Ctrl::LEFTDOUBLE, p); break; + case SDL_BUTTON_RIGHT: Ctrl::DoMouseFB(Ctrl::RIGHTDOUBLE, p); break; + case SDL_BUTTON_MIDDLE: Ctrl::DoMouseFB(Ctrl::MIDDLEDOUBLE, p); break; + } + isdblclick[bi] = 0; //reset, to go ahead sending repeats + } + else + { + lastbdowntime[bi] = ct; + isdblclick[bi] = 0; //prepare for repeat + switch(bi) + { + case SDL_BUTTON_LEFT: mouseb |= (1<<0); Ctrl::DoMouseFB(Ctrl::LEFTDOWN, p); break; + case SDL_BUTTON_RIGHT: mouseb |= (1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTDOWN, p); break; + case SDL_BUTTON_MIDDLE: mouseb |= (1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEDOWN, p); break; + } + } + } + break; + case SDL_MOUSEBUTTONUP: { + int bi = event->button.button; + isdblclick[bi] = 1; //indicate maybe a dblclick + + Point p(event->button.x, event->button.y); + switch(bi) + { + case SDL_BUTTON_LEFT: mouseb &= ~(1<<0); Ctrl::DoMouseFB(Ctrl::LEFTUP, p); break; + case SDL_BUTTON_RIGHT: mouseb &= ~(1<<1); Ctrl::DoMouseFB(Ctrl::RIGHTUP, p); break; + case SDL_BUTTON_MIDDLE: mouseb &= ~(1<<2); Ctrl::DoMouseFB(Ctrl::MIDDLEUP, p); break; + } + } + break; +/* case SDL_VIDEORESIZE: //SDL_ResizeEvent + { + width = event->resize.w; + height = event->resize.h; + + SDL_FreeSurface(screen); + screen = CreateScreen(width, height, bpp, videoflags); + ASSERT(screen); + Ctrl::SetFramebufferSize(Size(width, height)); + } + break; + case SDL_VIDEOEXPOSE: //SDL_ExposeEvent + break;*/ + case SDL_WINDOWEVENT: + switch (event->window.event) { + case SDL_WINDOWEVENT_SHOWN: + break; + case SDL_WINDOWEVENT_HIDDEN: + break; + case SDL_WINDOWEVENT_EXPOSED: + break; + case SDL_WINDOWEVENT_MOVED: + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + SDLwidth = event->window.data1; + SDLheight = event->window.data2; + break; + case SDL_WINDOWEVENT_RESIZED: + break; + case SDL_WINDOWEVENT_MINIMIZED: + break; + case SDL_WINDOWEVENT_MAXIMIZED: + break; + case SDL_WINDOWEVENT_RESTORED: + break; + case SDL_WINDOWEVENT_ENTER: + sdlMouseIsIn = true; + Invalidate(); + break; + case SDL_WINDOWEVENT_LEAVE: + sdlMouseIsIn = false; + Invalidate(); + break; + case SDL_WINDOWEVENT_FOCUS_GAINED: + break; + case SDL_WINDOWEVENT_FOCUS_LOST: + break; + case SDL_WINDOWEVENT_CLOSE: + break; + } + break; + case SDL_QUIT: //SDL_QuitEvent + Ctrl::EndSession(); + break; + } +} +#endif + +void Ctrl::MouseEventFB(Ptr t, int event, Point p, int zdelta) +{ + if(!t->IsEnabled()) + return; + Rect rr = t->GetRect(); + if((event & Ctrl::ACTION) == DOWN) { + Ptr q = t; + TopWindowFrame *wf = dynamic_cast(~t); + if(wf) + q = wf->window; + if(q) q->ClickActivateWnd(); + if(q) q->SetForeground(); + if(ignoreclick) + return; + } + if(t) + t->DispatchMouse(event, p - rr.TopLeft(), zdelta); + if(t) + t->PostInput(); +} + +Ctrl *Ctrl::FindMouseTopCtrl() +{ + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ctrl *t = topctrl[i]; + if(t->GetRect().Contains(fbmousepos)) + return t->IsEnabled() ? t : NULL; + } + return desktop->IsEnabled() ? desktop : NULL; +} + +void Ctrl::DoMouseFB(int event, Point p, int zdelta) +{ + fbmousepos = p; + int a = event & Ctrl::ACTION; + if(a == Ctrl::UP && Ctrl::ignoreclick) { + EndIgnore(); + return; + } + else + if(a == Ctrl::DOWN && ignoreclick) + return; + LLOG("### Mouse event: " << event << " position " << p << " zdelta " << zdelta << ", capture " << Upp::Name(captureCtrl)); + if(captureCtrl) + MouseEventFB(captureCtrl->GetTopCtrl(), event, p, zdelta); + else + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ptr t = topctrl[i]; + Rect rr = t->GetRect(); + if(rr.Contains(p)) { + MouseEventFB(t, event, p, zdelta); + return; + } + } + Ctrl *desktop = GetDesktop(); + if(desktop) { + desktop->DispatchMouse(event, p, zdelta); + desktop->PostInput(); + } +} + +bool Ctrl::DoKeyFB(dword key, int cnt) +{ + LLOG("DoKeyFB " << GetKeyDesc(key) << ", " << cnt); + + bool b = DispatchKey(key, cnt); + SyncCaret(); + Ctrl *desktop = GetDesktop(); + if(desktop) + desktop->PostInput(); + return b; +} + +void Ctrl::SetCaret(int x, int y, int cx, int cy) +{ + GuiLock __; + caretx = x; + carety = y; + caretcx = cx; + caretcy = cy; + fbCaretTm = GetTickCount(); + SyncCaret(); +} + +void Ctrl::SyncCaret() +{ + CursorSync(); +} + +void Ctrl::CursorSync() +{ + LLOG("@ CursorSync"); + Point p = GetMousePos() - fbCursorImage.GetHotSpot(); + Rect cr = Null; + if(focusCtrl && (((GetTickCount() - fbCaretTm) / 500) & 1) == 0) + cr = (RectC(focusCtrl->caretx, focusCtrl->carety, focusCtrl->caretcx, focusCtrl->caretcy) + + focusCtrl->GetScreenView().TopLeft()) & focusCtrl->GetScreenView(); + if(fbCursorPos != p && !SystemCursor || cr != fbCaretRect) { + fbCaretRect = cr; + fbCursorPos = p; + Invalidate(); + } +} + +bool Ctrl::ProcessEvent(bool *quit) +{ + LLOG("@ ProcessEvent"); + ASSERT(IsMainThread()); + if(!GetMouseLeft() && !GetMouseRight() && !GetMouseMiddle()) + ReleaseCtrlCapture(); + bool ret = SlaveGuiPtr->ProcessEvent(quit); +#if 0 + SDL_Event event; + if(SDL_PollEvent(&event)) { + if(event.type == SDL_QUIT && quit) + *quit = true; + HandleSDLEvent(&event); + ret = true; + } +#endif + DefferedFocusSync(); + SyncCaret(); + SyncTopWindows(); + return ret; +} + +bool Ctrl::ProcessEvents(bool *quit) +{ + //LOGBLOCK("@ ProcessEvents"); +// MemoryCheckDebug(); + bool ret = ProcessEvent(quit); + while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); + TimeStop tm; + LLOG("TimerProc invoked at " << msecs()); + TimerProc(GetTickCount()); + LLOG("TimerProc elapsed: " << tm); + SweepMkImageCache(); + DoPaint(); + return ret; +} + +void Ctrl::EventLoop(Ctrl *ctrl) +{ + GuiLock __; + ASSERT(IsMainThread()); + ASSERT(LoopLevel == 0 || ctrl); + LoopLevel++; + LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN); + Ptr ploop; + if(ctrl) { + ploop = LoopCtrl; + LoopCtrl = ctrl; + ctrl->inloop = true; + } + + bool quit = false; + int64 loopno = ++EventLoopNo; + ProcessEvents(&quit); + while(loopno > EndSessionLoopNo && !quit && (ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount())) + { +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); + SyncCaret(); + GuiSleep(20); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); + ProcessEvents(&quit); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); + LDUMP(loopno); + LDUMP(fbEndSessionLoop); + } + + if(ctrl) + LoopCtrl = ploop; + LoopLevel--; + LLOG(LOG_END << "Leaving event loop "); +} + +void Ctrl::GuiSleep(int ms) +{ + GuiLock __; + ASSERT(IsMainThread()); + LLOG("GuiSleep"); + int level = LeaveGuiMutexAll(); + SlaveGuiPtr->WaitEvent(ms); +#if 0 + SDL_WaitEventTimeout(NULL, ms); +#endif + EnterGuiMutex(level); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/FB.iml b/rainbow/SlaveGui/FB.iml new file mode 100644 index 000000000..c36090ae7 --- /dev/null +++ b/rainbow/SlaveGui/FB.iml @@ -0,0 +1,63 @@ +PREMULTIPLIED +IMAGE_ID(Arrow) +IMAGE_ID(IBeam) +IMAGE_ID(Wait) +IMAGE_ID(No) +IMAGE_ID(SizeAll) +IMAGE_ID(SizeHorz) +IMAGE_ID(SizeRight) +IMAGE_ID(SizeLeft) +IMAGE_ID(SizeVert) +IMAGE_ID(SizeTopLeft) +IMAGE_ID(SizeTop) +IMAGE_ID(SizeTopRight) +IMAGE_ID(SizeBottomLeft) +IMAGE_ID(SizeBottom) +IMAGE_ID(SizeBottomRight) +IMAGE_ID(overlap) +IMAGE_ID(maximize) +IMAGE_ID(close) +IMAGE_ID(bgtitle) +IMAGE_ID(title) +IMAGE_ID(border) +IMAGE_ID(Hand) + +IMAGE_BEGIN_DATA +IMAGE_DATA(120,156,237,90,61,104,20,65,20,30,77,162,9,92,144,248,135,160,133,117,42,177,18,21,4,171,84,65,76,22,4,149) +IMAGE_DATA(136,17,37,49,66,4,13,40,72,34,4,145,128,120,133,196,20,49,30,24,11,207,104,33,105,196,4,114,133,34,66,68) +IMAGE_DATA(52,129,67,20,65,4,145,52,218,217,61,103,214,157,117,118,110,126,222,91,247,240,135,157,229,177,55,51,223,247,230,205) +IMAGE_DATA(247,222,206,94,244,88,129,109,98,162,173,97,171,196,13,184,5,12,223,128,200,129,114,153,196,129,239,223,183,195,244,244) +IMAGE_DATA(22,44,7,190,125,219,13,95,191,238,131,169,169,29,24,14,172,172,28,128,47,95,186,225,243,231,195,48,62,190,223,199) +IMAGE_DATA(129,79,159,122,225,227,199,83,240,225,195,25,120,255,254,28,20,139,7,93,28,120,247,238,60,188,125,123,1,170,213,97) +IMAGE_DATA(88,90,186,2,175,95,95,131,177,177,99,54,14,44,47,143,194,155,55,87,225,213,171,235,240,242,229,4,188,120,113,7) +IMAGE_DATA(158,63,159,134,209,209,126,19,135,99,138,176,184,120,131,227,38,225,217,179,123,176,176,176,16,217,3,24,30,30,208,57) +IMAGE_DATA(220,215,4,199,77,194,211,167,119,160,82,121,24,98,75,165,146,196,169,22,226,43,149,91,220,74,48,63,127,23,230,230) +IMAGE_DATA(238,195,227,199,143,156,251,125,242,228,54,92,188,120,58,246,51,52,52,232,196,15,13,245,169,243,194,96,112,112,64,141) +IMAGE_DATA(33,129,55,105,208,223,127,210,170,167,97,44,92,163,183,247,152,109,13,83,131,158,158,35,148,186,13,215,8,130,110,210) +IMAGE_DATA(26,93,93,7,41,248,128,16,143,185,53,177,117,108,53,91,27,26,211,18,47,76,54,237,115,28,176,214,255,231,199,44) +IMAGE_DATA(251,173,209,133,21,184,112,77,92,180,166,164,112,88,11,51,183,245,222,184,211,20,44,147,248,109,101,179,41,248,120,83) +IMAGE_DATA(155,175,93,50,114,196,152,152,211,240,65,203,174,157,176,254,236,137,4,71,124,22,99,98,142,25,158,36,149,227,193,38) +IMAGE_DATA(56,98,125,97,30,108,204,209,180,115,98,9,254,41,241,83,245,161,234,79,201,47,181,126,104,245,217,198,175,230,232,178) +IMAGE_DATA(9,103,33,163,143,70,132,89,147,230,193,81,230,93,241,186,252,164,225,215,36,80,233,99,215,183,125,166,196,111,138,139) +IMAGE_DATA(194,151,205,231,195,199,247,249,192,240,77,62,108,251,196,232,100,251,236,203,117,205,97,237,136,203,23,131,105,140,194,255) +IMAGE_DATA(157,231,129,82,79,212,231,22,227,203,204,69,28,72,63,189,242,38,94,217,226,142,8,194,200,47,151,203,130,15,209,157) +IMAGE_DATA(228,71,229,243,110,42,63,81,252,9,97,162,109,185,14,139,68,12,160,180,200,101,220,92,177,168,92,137,83,125,216,48) +IMAGE_DATA(166,253,171,241,234,62,212,125,170,250,232,250,233,205,54,166,250,49,233,135,53,25,119,22,113,100,161,71,86,121,201,170) +IMAGE_DATA(62,212,102,210,153,82,167,186,62,204,160,95,26,63,105,248,170,31,148,6,109,252,107,127,51,107,8,77,39,251,4,176) +IMAGE_DATA(9,109,43,22,155,15,234,195,99,106,236,15,60,60,152,56,178,208,35,147,188,228,137,206,19,157,39,250,127,74,244,90) +IMAGE_DATA(158,234,134,40,213,186,67,87,2,93,137,241,9,174,196,155,16,72,235,199,65,203,57,211,134,254,230,57,215,254,92,186) +IMAGE_DATA(184,244,116,229,65,205,83,77,254,90,249,181,38,186,106,235,19,87,61,166,96,41,28,204,151,17,149,211,222,222,142,230) +IMAGE_DATA(72,49,132,117,118,118,122,121,74,18,2,41,40,134,167,182,44,121,152,167,88,231,97,79,15,201,19,122,178,72,91,44) +IMAGE_DATA(135,41,249,195,228,91,47,106,12,199,88,139,249,201,84,191,57,215,254,92,186,212,253,100,114,53,107,165,120,56,212,138) +IMAGE_DATA(76,83,249,212,39,140,250,36,83,79,12,204,201,164,36,27,125,2,74,61,169,39,173,212,132,114,162,51,150,254,205,193) +IMAGE_DATA(8,111,40,106,77,229,5,155,23,172,147,195,254,182,130,205,95,165,245,155,115,237,207,165,75,221,95,165,105,42,69,110) +IMAGE_DATA(66,15,150,194,201,191,228,219,121,174,19,208,198,251,175,191,228,23,248,149,81,3,143,153,240,46,95,105,241,152,56,116) +IMAGE_DATA(188,111,205,172,240,24,125,234,165,139,58,70,201,19,190,101,80,76,190,224,40,98,153,48,57,62,123,60,37,95,248,246) +IMAGE_DATA(187,197,180,177,177,49,216,219,218,10,226,142,153,19,253,61,220,244,113,137,149,115,182,113,209,55,141,153,214,13,231,11) +IMAGE_DATA(133,208,108,216,4,71,96,35,156,248,108,195,82,241,148,120,168,251,77,171,39,54,95,164,214,200,47,217,186,186,38,224) +IMAGE_DATA(80,223,12,28,189,60,3,199,111,206,0,181,31,59,107,8,255,111,102,4,90,218,203,176,33,88,134,109,195,226,37,76) +IMAGE_DATA(236,139,50,111,226,87,244,183,44,246,121,74,188,249,125,77,252,166,90,197,255,250,77,182,217,70,70,70,114,124,157,240) +IMAGE_DATA(178,239,179,52,181,16,22,147,227,31,70,228,175,156,212,187,11,7,197,98,49,113,183,112,226,249,106,181,154,184,91,56) +IMAGE_DATA(53,56,121,87,214,97,234,198,108,120,101,157,56,142,142,142,14,52,94,244,165,97,240,179,179,179,9,142,201,20,124,32) +IMAGE_DATA(98,17,49,33,241,94,142,88,95,195,199,28,19,94,140,219,114,230,139,229,7,18,241,124,50,0,0,0,0,0,0,0) +IMAGE_END_DATA(1184, 22) diff --git a/rainbow/SlaveGui/Gui.h b/rainbow/SlaveGui/Gui.h new file mode 100644 index 000000000..fb5f0bc4d --- /dev/null +++ b/rainbow/SlaveGui/Gui.h @@ -0,0 +1,358 @@ +#define GUI_SLAVE + +NAMESPACE_UPP + +class SystemDraw : public Draw { +public: + virtual dword GetInfo() const; + virtual Size GetPageSize() const; + + virtual void BeginOp(); + virtual void EndOp(); + virtual void OffsetOp(Point p); + virtual bool ClipOp(const Rect& r); + virtual bool ClipoffOp(const Rect& r); + virtual bool ExcludeClipOp(const Rect& r); + virtual bool IntersectClipOp(const Rect& r); + virtual bool IsPaintingOp(const Rect& r) const; + virtual Rect GetPaintRect() const; + + virtual void DrawRectOp(int x, int y, int cx, int cy, Color color); + virtual void DrawImageOp(int x, int y, int cx, int cy, const Image& img, const Rect& src, Color color); + virtual void DrawLineOp(int x1, int y1, int x2, int y2, int width, Color color); + + virtual void DrawPolyPolylineOp(const Point *vertices, int vertex_count, + const int *counts, int count_count, + int width, Color color, Color doxor); + virtual void DrawPolyPolyPolygonOp(const Point *vertices, int vertex_count, + const int *subpolygon_counts, int scc, + const int *disjunct_polygon_counts, int dpcc, + Color color, int width, Color outline, + uint64 pattern, Color doxor); + virtual void DrawArcOp(const Rect& rc, Point start, Point end, int width, Color color); + + virtual void DrawEllipseOp(const Rect& r, Color color, int pen, Color pencolor); + virtual void DrawTextOp(int x, int y, int angle, const wchar *text, Font font, + Color ink, int n, const int *dx); + + virtual Size GetNativeDpi() const; + virtual void BeginNative(); + virtual void EndNative(); + + virtual int GetCloffLevel() const; + +private: + Size pageSize; + Size nativeSize; + Size nativeDpi; + bool palette:1; + bool color16:1; + bool is_mono:1; + int native; + + friend class ImageDraw; + friend class FontInfo; + friend class Font; + + friend void StaticExitDraw_(); + + Point actual_offset_bak; + + struct Cloff : Moveable { + Point org; + HRGN hrgn; + Rect drawingclip; + }; + + Array cloff; + Rect drawingclip; + + COLORREF lastTextColor; + Color lastColor; + HBRUSH orgBrush; + HBRUSH actBrush; + HPEN orgPen; + HPEN actPen; + int lastPen; + Color lastPenColor; + + void Unselect0(); + void Cinit(); + + void LoadCaps(); + void SetPrinterMode(); + void Reset(); + void SetOrg(); + friend HPALETTE GetQlibPalette(); + void DotsMode(); + + static void InitColors(); + + friend class BackDraw; + friend class ScreenDraw; + friend class PrintDraw; + +protected: + dword style; + HDC handle; + Point actual_offset; + + SystemDraw(); + void Init(); + void InitClip(const Rect& clip); + +public: + static Rect GetVirtualScreenArea(); + + static void SetAutoPalette(bool ap); + static bool AutoPalette(); + bool PaletteMode() { return palette; } + + static void Flush() { GdiFlush(); } + + COLORREF GetColor(Color color) const; + + Point GetOffset() const { return actual_offset; } + +#ifndef PLATFORM_WINCE + Point LPtoDP(Point p) const; + Point DPtoLP(Point p) const; + Rect LPtoDP(const Rect& r) const; + Rect DPtoLP(const Rect& r) const; +#endif + + void SetColor(Color color); + void SetDrawPen(int width, Color color); + + Size GetSizeCaps(int i, int j) const; + HDC BeginGdi(); + void EndGdi(); + HDC GetHandle() { return handle; } + operator HDC() const { return handle; } + void Unselect(); + void Attach(HDC ahandle) { handle = ahandle; Init(); } + HDC Detach() { Unselect(); HDC h = handle; handle = NULL; return h; } + + SystemDraw(HDC hdc); + virtual ~SystemDraw(); + + bool CanSetSurface() { return IsGui() && IsWinNT(); } +}; + +#ifndef PLATFORM_WINCE +class WinMetaFile { + Size size; + HENHMETAFILE hemf; + + void Init(); + +public: + void Attach(HENHMETAFILE emf); + HENHMETAFILE Detach(); + + void Set(const void *data, dword len); + void Set(const String& data) { Set(~data, data.GetCount()); } + + String Get() const; + + operator bool() const { return hemf; } + void SetSize(const Size& sz) { size = sz; } + Size GetSize() const { return hemf ? size : Size(0, 0); } + + void Clear(); + + void Paint(Draw& w, const Rect& r) const; + void Paint(Draw& w, int x, int y, int cx, int cy) const; + + void Serialize(Stream& s); + + void ReadClipboard(); + void WriteClipboard() const; + void Load(const char *file) { Set(LoadFile(file)); } + + WinMetaFile() { Init(); } + WinMetaFile(HENHMETAFILE hemf); + WinMetaFile(HENHMETAFILE hemf, Size sz); + WinMetaFile(const char *file); + WinMetaFile(void *data, int len); + WinMetaFile(const String& data); + + ~WinMetaFile() { Clear(); } + + HENHMETAFILE GetHEMF() const { return hemf; } +}; + +class WinMetaFileDraw : public SystemDraw { + Size size; + +public: + bool Create(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + bool Create(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFile Close(); + + WinMetaFileDraw() {} + WinMetaFileDraw(HDC hdc, int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + WinMetaFileDraw(int cx, int cy, const char *app = NULL, const char *name = NULL, const char *file = NULL); + ~WinMetaFileDraw(); +}; + +void DrawWMF(Draw& w, int x, int y, int cx, int cy, const String& wmf); +void DrawWMF(Draw& w, int x, int y, const String& wmf); +Drawing LoadWMF(const char *path, int cx, int cy); +Drawing LoadWMF(const char *path); + +String AsWMF(const Drawing& iw); + +#endif + +class ScreenDraw : public SystemDraw { +public: + ScreenDraw(bool ic = false); + ~ScreenDraw(); +}; + +#ifndef PLATFORM_WINCE +class PrintDraw : public SystemDraw { +public: + virtual void StartPage(); + virtual void EndPage(); + +private: + bool aborted; + + void InitPrinter(); +public: + PrintDraw(HDC hdc, const char *jobname); + ~PrintDraw(); +}; +#endif + +inline bool BitBlt(HDC ddc, Point d, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return BitBlt(ddc, d.x, d.y, s.Width(), s.Height(), sdc, s.left, s.top, rop); } + +inline bool StretchBlt(HDC ddc, const Rect& r, HDC sdc, const Rect& s, dword rop = SRCCOPY) +{ return StretchBlt(ddc, r.left, r.top, r.Width(), r.Height(), sdc, s.left, s.top, s.Width(), s.Height(), rop); } + +inline bool PatBlt(HDC dc, const Rect& r, dword rop = PATCOPY) +{ return PatBlt(dc, r.left, r.top, r.Width(), r.Height(), rop); } + +inline void MoveTo(HDC hdc, Point pt) { MoveToEx(hdc, pt.x, pt.y, 0); } +inline void LineTo(HDC hdc, Point pt) { LineTo(hdc, pt.x, pt.y); } + +inline void DrawLine(HDC hdc, Point p, Point q) { MoveTo(hdc, p); LineTo(hdc, q); } +inline void DrawLine(HDC hdc, int px, int py, int qx, int qy) { MoveToEx(hdc, px, py, 0); LineTo(hdc, qx, qy); } + +#ifndef PLATFORM_WINCE +inline void DrawArc(HDC hdc, const Rect& rc, Point p, Point q){ Arc(hdc, rc.left, rc.top, rc.right, rc.bottom, p.x, p.y, q.x, q.y); } +#endif +inline void DrawCircle(HDC hdc, int x, int y, int radius) { Ellipse(hdc, x - radius, y - radius, x + radius + 1, y + radius + 1); } +inline void DrawCircle(HDC hdc, Point centre, int radius) { DrawCircle(hdc, centre.x, centre.y, radius); } +inline void DrawEllipse(HDC hdc, const Rect& rc) { Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +inline void DrawRect(HDC hdc, const Rect& rc) { Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } + +HDC ScreenHDC(); +HPALETTE GetQlibPalette(); + +Image Win32Icon(LPCSTR id, int iconsize = 0); +Image Win32Icon(int id, int iconsize = 0); +Image Win32Cursor(LPCSTR id); +Image Win32Cursor(int id); +HICON IconWin32(const Image& img, bool cursor = false); +Image Win32DllIcon(const char *dll, int ii, bool large); + +class BackDraw : public SystemDraw { +public: + virtual bool IsPaintingOp(const Rect& r) const; + +protected: + HBITMAP hbmpold; + HBITMAP hbmp; + + Size size; + Draw *painting; + Point painting_offset; + +public: + void Put(SystemDraw& w, int x, int y); + void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); } + + void Create(SystemDraw& w, int cx, int cy); + void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); } + void Destroy(); + + void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; } + + BackDraw(); + ~BackDraw(); +}; + +class ImageDraw : public SystemDraw { + Size size; + + struct Section { + HDC dc; + HBITMAP hbmp, hbmpOld; + RGBA *pixels; + + void Init(int cx, int cy); + ~Section(); + }; + + Section rgb; + Section a; + SystemDraw alpha; + + + bool has_alpha; + + void Init(); + Image Get(bool pm) const; + +public: + Draw& Alpha(); + + operator Image() const; + + Image GetStraight() const; + + ImageDraw(Size sz); + ImageDraw(int cx, int cy); + ~ImageDraw(); +}; + +END_UPP_NAMESPACE + +#define GUIPLATFORM_KEYCODES_INCLUDE "Win32Keys.h" + + +#define GUIPLATFORM_CTRL_TOP_DECLS \ + HWND hwnd; \ + UDropTarget *dndtgt; \ + + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE "Win32Ctrl.h" + + +#define GUIPLATFORM_PASTECLIP_DECLS \ + UDropTarget *dt; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE "Win32Top.h" + +NAMESPACE_UPP + +inline unsigned GetHashValue(const HWND& hwnd) +{ + return (unsigned)(intptr_t)hwnd; +} +END_UPP_NAMESPACE + +#ifdef PLATFORM_WIN32 +#ifndef PLATFORM_WINCE + +#include + +#endif +#endif + +#define GUIPLATFORM_INCLUDE_AFTER "Win32GuiA.h" diff --git a/rainbow/SlaveGui/Image.cpp b/rainbow/SlaveGui/Image.cpp new file mode 100644 index 000000000..a7376c0d3 --- /dev/null +++ b/rainbow/SlaveGui/Image.cpp @@ -0,0 +1,47 @@ +#include + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LTIMING(x) // RTIMING(x) + +void SetSurface(SystemDraw& w, int x, int y, int cx, int cy, const RGBA *pixels) +{ + GuiLock __; + // Empty as CanSetSurface is false +} + +void SetSurface(SystemDraw& w, const Rect& dest, const RGBA *pixels, Size psz, Point poff) +{ + GuiLock __; + // Empty as CanSetSurface is false +} + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +#define STD_CURSOR(name, sdl) \ +Image Image::name() { static Image img; ONCELOCK { img = FBImg::name(); img.SetAuxData(sdl + 1); } return img; } + +STD_CURSOR(Arrow, SDL_SYSTEM_CURSOR_ARROW) +STD_CURSOR(Wait, SDL_SYSTEM_CURSOR_WAIT) +STD_CURSOR(IBeam, SDL_SYSTEM_CURSOR_IBEAM) +STD_CURSOR(No, SDL_SYSTEM_CURSOR_NO) +STD_CURSOR(SizeAll, SDL_SYSTEM_CURSOR_SIZEALL) +STD_CURSOR(SizeHorz, SDL_SYSTEM_CURSOR_SIZEWE) +STD_CURSOR(SizeVert, SDL_SYSTEM_CURSOR_SIZENS) +STD_CURSOR(SizeTopLeft, SDL_SYSTEM_CURSOR_SIZENWSE) +STD_CURSOR(SizeTop, SDL_SYSTEM_CURSOR_SIZENS) +STD_CURSOR(SizeTopRight, SDL_SYSTEM_CURSOR_SIZENESW) +STD_CURSOR(SizeLeft, SDL_SYSTEM_CURSOR_SIZEWE) +STD_CURSOR(SizeRight, SDL_SYSTEM_CURSOR_SIZEWE) +STD_CURSOR(SizeBottomLeft, SDL_SYSTEM_CURSOR_SIZENWSE) +STD_CURSOR(SizeBottom, SDL_SYSTEM_CURSOR_SIZENS) +STD_CURSOR(SizeBottomRight, SDL_SYSTEM_CURSOR_SIZENESW) +STD_CURSOR(Hand, SDL_SYSTEM_CURSOR_HAND) + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Keys.h b/rainbow/SlaveGui/Keys.h new file mode 100644 index 000000000..867c02403 --- /dev/null +++ b/rainbow/SlaveGui/Keys.h @@ -0,0 +1,123 @@ +//handled extra in fbKEYtoK +K_TAB = 9, //SDLK_TAB, + +K_SPACE = 32, //SDLK_SPACE, + +K_RETURN = 13, //SDLK_RETURN, +K_ENTER = K_RETURN, + +K_BACK = K_DELTA, +K_BACKSPACE, + +K_SHIFT_KEY, +K_CTRL_KEY, +K_ALT_KEY, +K_CAPSLOCK, +K_ESCAPE, +K_PRIOR, +K_PAGEUP, +K_NEXT, +K_PAGEDOWN, +K_END, +K_HOME, +K_LEFT, +K_UP, +K_RIGHT, +K_DOWN, +K_INSERT, +K_DELETE, + +K_NUMPAD0, +K_NUMPAD1, +K_NUMPAD2, +K_NUMPAD3, +K_NUMPAD4, +K_NUMPAD5, +K_NUMPAD6, +K_NUMPAD7, +K_NUMPAD8, +K_NUMPAD9, +K_MULTIPLY, +K_ADD, +K_SEPARATOR, +K_SUBTRACT, +K_DECIMAL, +K_DIVIDE, +K_SCROLL, + +K_F1, +K_F2, +K_F3, +K_F4, +K_F5, +K_F6, +K_F7, +K_F8, +K_F9, +K_F10, +K_F11, +K_F12, + +K_A, +K_B, +K_C, +K_D, +K_E, +K_F, +K_G, +K_H, +K_I, +K_J, +K_K, +K_L, +K_M, +K_N, +K_O, +K_P, +K_Q, +K_R, +K_S, +K_T, +K_U, +K_V, +K_W, +K_X, +K_Y, +K_Z, +K_0, +K_1, +K_2, +K_3, +K_4, +K_5, +K_6, +K_7, +K_8, +K_9, + +K_CTRL_LBRACKET, +K_CTRL_RBRACKET, +K_CTRL_MINUS, +K_CTRL_GRAVE, +K_CTRL_SLASH, +K_CTRL_BACKSLASH, +K_CTRL_COMMA, +K_CTRL_PERIOD, +K_CTRL_SEMICOLON, +K_CTRL_EQUAL, +K_CTRL_APOSTROPHE, + +K_BREAK, // Is it really? + +K_PLUS, +K_MINUS, +K_COMMA, +K_PERIOD, +K_SEMICOLON, + +K_SLASH, +K_GRAVE, +K_LBRACKET, +K_BACKSLASH, +K_RBRACKET, +K_QUOTEDBL, diff --git a/rainbow/SlaveGui/Local.h b/rainbow/SlaveGui/Local.h new file mode 100644 index 000000000..2db2f30f7 --- /dev/null +++ b/rainbow/SlaveGui/Local.h @@ -0,0 +1,65 @@ +#include + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +class TopWindowFrame : public Ctrl { +public: + virtual void Layout(); + virtual void Paint(Draw& w); + virtual Image CursorImage(Point p, dword keyflags); + virtual void LeftDown(Point p, dword keyflags); + virtual void LeftHold(Point p, dword keyflags); + virtual void LeftDouble(Point p, dword keyflags); + virtual void MouseMove(Point p, dword keyflags); + virtual void CancelMode(); + virtual void LeftUp(Point p, dword keyflags); + +private: + Point dir; + Point startpos; + Rect startrect; + + bool maximized; + Rect overlapped; + + bool holding; + TimeCallback hold; + + Point GetDragMode(Point p); + Image GetDragImage(Point dragmode); + void StartDrag(); + Rect Margins() const; + Rect ComputeClient(Rect r); + void Hold(); + + typedef TopWindowFrame CLASSNAME; + +public: + String title; + Button close, maximize; + Image icon; + Size minsize; + bool sizeable; + TopWindow *window; + + void SetTitle(const String& s) { title = s; Refresh(); } + Rect GetClient() const; + void SetClient(Rect r); + void GripResize(); + + void Maximize(); + void Overlap(); + void ToggleMaximize(); + bool IsMaximized() const { return maximized; } + void SyncRect(); + + TopWindowFrame(); +}; + +extern Size screen_size; + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/SDL.cpp b/rainbow/SlaveGui/SDL.cpp new file mode 100644 index 000000000..8d14c17b0 --- /dev/null +++ b/rainbow/SlaveGui/SDL.cpp @@ -0,0 +1,81 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) //LOG(x) + +dword SDLsettings; + +void USDLSetup(dword flags) +{ + SDLsettings = flags; +} + +Size screen_size; +// SDLWindow screen; + +SDL_TimerID waketimer_id = 0; +Uint32 WakeCb(Uint32 interval, void *param) +{ + //wake up message que, FIXME maybe it can be done better? + SDL_Event event; + event.type=SDL_USEREVENT; + SDL_PushEvent(&event); + return 0; +} + +void WakeUpGuiThread() +{ + waketimer_id = SDL_AddTimer(20, WakeCb, NULL); +} + +void FBInit() +{ + GuiLock __; + + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER); + + Ctrl::InitFB(); + +#if 0 + if(SDL_Init(SDL_INIT_VIDEO/* | SDL_INIT_TIMER*/) < 0) //timer not needed, we post to queue directly + { + Cout() << Format("Couldn't initialize SDL: %s\n", SDL_GetError()); + return; + } + +// TODO +// SDL_EnableUNICODE(1); //for unicode keycode availability +// SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL/2); +// SDL_ShowCursor(0); + + const SDL_VideoInfo* vi = SDL_GetVideoInfo(); + //ASSERT(vi->hw_available); + + width = vi->current_w; + height = vi->current_h; + bpp = vi->vfmt->BitsPerPixel; + ASSERT(bpp == 32); + + //FIXME adjustable + videoflags = SDL_HWSURFACE | SDL_HWACCEL | SDL_DOUBLEBUF | SDL_RESIZABLE;// | SDL_NOFRAME | SDL_FULLSCREEN; +#endif + screen_size = Size(1500, 900); + screen.Create(Rect(Point(20, 20), screen_size), "First test"); + + Ctrl::SetDesktopSize(screen_size); +} + +void FBDeInit() +{ + SDL_RemoveTimer(waketimer_id); + Ctrl::ExitFB(); + screen.Destroy(); + SDL_Quit(); +} + +END_UPP_NAMESPACE + +#endif \ No newline at end of file diff --git a/rainbow/SlaveGui/SlaveGui.h b/rainbow/SlaveGui/SlaveGui.h new file mode 100644 index 000000000..c27d61001 --- /dev/null +++ b/rainbow/SlaveGui/SlaveGui.h @@ -0,0 +1,118 @@ +#define GUI_SLAVE + +#ifdef PLATFORM_POSIX +#include +#endif + +NAMESPACE_UPP + +#define IMAGECLASS FBImg +#define IMAGEFILE +#include + +/* +struct SDLWindow { + SDL_Window *win; + SDL_GLContext glcontext; + int64 serial; + + bool Create(const Rect& rect, const char *title); + void Destroy(); + + operator bool() const { return win; } + + SDLWindow(); + ~SDLWindow(); +}; +*/ + +class SystemDraw/* : public GLDraw*/ { +public: + bool CanSetSurface() { return false; } + static void Flush() {} +}; + +struct BackDraw__ : public SystemDraw { + BackDraw__() : SystemDraw() {} +}; + +class BackDraw : public BackDraw__ { // Dummy only, as we are running in GlobalBackBuffer mode + Size size; + Draw *painting; + Point painting_offset; + ImageBuffer ib; + +public: + virtual bool IsPaintingOp(const Rect& r) const; + +public: + void Put(SystemDraw& w, int x, int y) {} + void Put(SystemDraw& w, Point p) { Put(w, p.x, p.y); } + + void Create(SystemDraw& w, int cx, int cy) {} + void Create(SystemDraw& w, Size sz) { Create(w, sz.cx, sz.cy); } + void Destroy() {} + + void SetPaintingDraw(Draw& w, Point off) { painting = &w; painting_offset = off; } + + BackDraw(); + ~BackDraw(); +}; + +class ImageDraw : public SImageDraw { +public: + ImageDraw(Size sz) : SImageDraw(sz) {} + ImageDraw(int cx, int cy) : SImageDraw(cx, cy) {} +}; + +void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rect& clip, int n, + Color color, uint64 pattern); + +class TopWindowFrame; + +#define GUIPLATFORM_CTRL_TOP_DECLS Ctrl *owner_window; + +#define GUIPLATFORM_CTRL_DECLS_INCLUDE + +#define GUIPLATFORM_PASTECLIP_DECLS \ + bool dnd; \ + friend struct DnDLoop; \ + +#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE + +class PrinterJob { // Dummy only... + NilDraw nil; + Vector pages; + +public: + Draw& GetDraw() { return nil; } + operator Draw&() { return GetDraw(); } + const Vector& GetPages() const { return pages; } + int operator[](int i) const { return 0; } + int GetPageCount() const { return 0; } + + bool Execute() { return false; } + + PrinterJob& Landscape(bool b = true) { return *this; } + PrinterJob& MinMaxPage(int minpage, int maxpage) { return *this; } + PrinterJob& PageCount(int n) { return *this; } + PrinterJob& CurrentPage(int currentpage) { return *this; } + PrinterJob& Name(const char *_name) { return *this; } + + PrinterJob(const char *name = NULL) {} + ~PrinterJob() {} +}; + +struct SlaveGui { + bool ProcessEvent(bool *quit); + void WaitEvent(int ms); + void SetMouseCursor(const Image& image); + void Quit(); + bool IsWaitingEvent(); +}; + +extern SlaveGui *SlaveGuiPtr; + +END_UPP_NAMESPACE + +#define GUIPLATFORM_INCLUDE_AFTER diff --git a/rainbow/SlaveGui/SlaveGui.upp b/rainbow/SlaveGui/SlaveGui.upp new file mode 100644 index 000000000..2db7ecfa5 --- /dev/null +++ b/rainbow/SlaveGui/SlaveGui.upp @@ -0,0 +1,34 @@ +description "SlaveGui backend\377"; + +uses + Painter, + CtrlLib, + GLDraw, + PdfDraw; + +library(POSIX) "SDL2 SDL2main GL"; + +library(WIN32) "SDL2.lib SDL2main.lib OpenGL32.lib"; + +file + SlaveGui.h, + Keys.h, + Local.h, + After.h, + Window.cpp, + Image.cpp, + FB.iml, + Ctrl.h, + DrawDragRect.cpp, + Ctrl.cpp, + Wnd.cpp, + Cursor.cpp, + Event.cpp, + Top.h, + TopFrame.cpp, + Top.cpp, + Clip.cpp, + DnD.cpp, + ChSysInit.cpp, + SDL.cpp; + diff --git a/rainbow/SlaveGui/Top.cpp b/rainbow/SlaveGui/Top.cpp new file mode 100644 index 000000000..bd14d5605 --- /dev/null +++ b/rainbow/SlaveGui/Top.cpp @@ -0,0 +1,149 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) + +void TopWindow::SyncFrameRect(const Rect& r) +{ + frame->SetClient(r); +} + +void TopWindow::DestroyFrame() +{ + if(frame->IsOpen()) + frame->DestroyWnd(); +} + +void TopWindow::GripResize() +{ + frame->GripResize(); +} + +void TopWindow::SyncSizeHints() +{ + SyncCaption(); +} + +void TopWindow::SyncTitle() +{ + SyncCaption(); +} + +void TopWindow::SyncCaption() +{ + GuiLock __; + frame->title = title.ToString(); + frame->minsize = minsize; + frame->close.Show(!noclosebox); + frame->maximize.Show(maximizebox); + frame->sizeable = sizeable; + frame->RefreshLayout(); + frame->Refresh(); + frame->close << [=] { WhenClose(); }; + frame->icon = icon; + frame->Enable(IsEnabled()); +} + +void TopWindow::State(int reason) +{ + SyncCaption(); +} + +void TopWindow::SyncRect() +{ + frame->SyncRect(); + Rect r = frame->GetClient(); + if(r != GetRect()) + SetRect(r); +} + +void TopWindow::Open(Ctrl *owner) +{ + GuiLock __; + LLOG("Open " << Upp::Name(owner)); + Rect r = GetRect(); + if(r.IsEmpty()) + SetRect(GetDefaultWindowRect()); + else + if(r.left == 0 && r.top == 0) + if(owner && center == 1) + SetRect(owner->GetRect().CenterRect(r.GetSize())); + else + if(center) + SetRect(GetWorkArea().CenterRect(r.GetSize())); + frame->SetClient(GetRect()); + frame->window = this; + frame->PopUp(owner, false, true); + PopUp(frame, false, true); + popup = false; + SetRect(frame->GetClient()); + SyncCaption(); + if(state == MAXIMIZED) + frame->Maximize(); +} + +void TopWindow::Open() +{ + Open(GetActiveCtrl()); +} + +void TopWindow::OpenMain() +{ + Open(NULL); +} + +void TopWindow::Minimize(bool effect) +{ +// state = MINIMIZED; +} + +TopWindow& TopWindow::FullScreen(bool b) +{ + return *this; +} + +void TopWindow::Maximize(bool effect) +{ + state = MAXIMIZED; + frame->Maximize(); +} + +void TopWindow::Overlap(bool effect) +{ + GuiLock __; + state = OVERLAPPED; + frame->Overlap(); +} + +TopWindow& TopWindow::TopMost(bool b, bool stay_top) +{ + GuiLock __; + return *this; +} + +bool TopWindow::IsTopMost() const +{ + return true; +} + +void TopWindow::GuiPlatformConstruct() +{ + frame = new TopWindowFrame; +} + +void TopWindow::GuiPlatformDestruct() +{ + delete frame; +} + +void TopWindow::SerializePlacement(Stream& s, bool reminimize) +{ + GuiLock __; +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Top.h b/rainbow/SlaveGui/Top.h new file mode 100644 index 000000000..2e9b12c16 --- /dev/null +++ b/rainbow/SlaveGui/Top.h @@ -0,0 +1,16 @@ +//$ class TopWindow { +public: + virtual void State(int reason); + +private: + TopWindowFrame *frame; + + void SyncRect(); + void SyncFrameRect(const Rect& r); + void DestroyFrame(); + + friend class Ctrl; + +public: + void GripResize(); +//$ }; diff --git a/rainbow/SlaveGui/TopFrame.cpp b/rainbow/SlaveGui/TopFrame.cpp new file mode 100644 index 000000000..27c71c80e --- /dev/null +++ b/rainbow/SlaveGui/TopFrame.cpp @@ -0,0 +1,236 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) // LOG(x) +#define LDUMP(x) //DDUMP(x) + +TopWindowFrame::TopWindowFrame() +{ + close.SetImage(FBImg::close()); + close.EdgeStyle(); + Add(close); + maximize.SetImage(FBImg::maximize()); + maximize.EdgeStyle(); + Add(maximize); + maximize <<= THISBACK(ToggleMaximize); + maximized = false; + sizeable = false; + holding = false; +} + +void TopWindowFrame::SyncRect() +{ + if(maximized) { + Size sz = GetWorkArea().GetSize(); + if(GetRect().GetSize() != sz) + SetRect(sz); + } +} + +void TopWindowFrame::Maximize() +{ + if(!maximized && maximize.IsShown()) { + maximized = true; + overlapped = GetRect(); + SetRect(GetWorkArea().GetSize()); + maximize.SetImage(FBImg::overlap()); + } +} + +void TopWindowFrame::Overlap() +{ + if(maximized && maximize.IsShown()) { + maximized = false; + SetRect(overlapped); + maximize.SetImage(FBImg::maximize()); + } +} + +void TopWindowFrame::ToggleMaximize() +{ + if(maximized) + Overlap(); + else + Maximize(); +} + +Rect TopWindowFrame::Margins() const +{ + return maximized ? Rect(0, 0, 0, 0) : ChMargins(FBImg::border()); +} + +void TopWindowFrame::Paint(Draw& w) +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + ChPaintEdge(w, sz, FBImg::border()); + ChPaint(w, m.left, m.top, sz.cx - m.left - m.right, GetStdFontCy() + 4, + window->IsForeground() ? FBImg::title() : FBImg::bgtitle()); + int tx = m.left + 2; + int tcx = sz.cx - m.left - m.right - 4 - c * (close.IsShown() + maximize.IsShown()); + if(!IsNull(icon)) { + Image h = icon; + if(h.GetWidth() > c || h.GetHeight() > c) + h = Rescale(h, GetFitSize(h.GetSize(), Size(c))); + w.DrawImage(tx, m.top + 2, h); + tx += c; + tcx -= c; + } + DrawTextEllipsis(w, tx, m.top + 2, tcx, title, "..", StdFont(), SColorHighlightText()); +} + +void TopWindowFrame::Layout() +{ + Size sz = GetSize(); + Rect m = Margins(); + int c = GetStdFontCy() + 4; + int x = sz.cx - m.right; + if(close.IsShown()) + close.SetRect(x -= c, m.top, c, c); + if(maximize.IsShown()) + maximize.SetRect(x -= c, m.top, c, c); +} + +Rect TopWindowFrame::GetClient() const +{ + Rect r = GetRect(); + Rect m = Margins(); + r.left += m.left; + r.right -= m.right; + r.top += m.top; + r.bottom -= m.bottom; + r.top += GetStdFontCy() + 4; + return r; +} + +Rect TopWindowFrame::ComputeClient(Rect r) +{ + Rect m = Margins(); + r.left -= m.left; + r.right += m.right; + r.top -= m.top; + r.bottom += m.bottom; + r.top -= GetStdFontCy() + 4; + return r; +} + +void TopWindowFrame::SetClient(Rect r) +{ + SetRect(ComputeClient(r)); +} + +Point TopWindowFrame::GetDragMode(Point p) +{ + Size sz = GetSize(); + Rect m = ChMargins(FBImg::border()); + Point dir; + dir.y = p.y < m.top ? -1 : p.y > sz.cy - m.top ? 1 : 0; + dir.x = p.x < m.left ? -1 : p.x > sz.cx - m.right ? 1 : 0; + return dir; +} + +void TopWindowFrame::StartDrag() +{ + if(maximized) + return; + if(!sizeable && (dir.x || dir.y)) + return; + SetCapture(); + startrect = GetRect(); + startpos = GetMousePos(); + LLOG("START DRAG ---------------"); +} + +void TopWindowFrame::GripResize() +{ + dir = Point(1, 1); + StartDrag(); +} + +void TopWindowFrame::LeftDown(Point p, dword keyflags) +{ + dir = GetDragMode(p); + StartDrag(); +} + +void TopWindowFrame::CancelMode() +{ + holding = false; +} + +void TopWindowFrame::LeftUp(Point p, dword keyflags) +{ + holding = false; +} + +void TopWindowFrame::Hold() +{ + if(HasCapture()) { + if(HasMouse() && GetMouseLeft() && holding) + StartDrag(); + ReleaseCapture(); + holding = false; + } +} + +void TopWindowFrame::LeftHold(Point p, dword keyflags) +{ +/* if(HasCapture() || FullWindowDrag) + return; + dir = GetDragMode(p); + if(!dir.x && !dir.y) + StartDrag();*/ +} + +void TopWindowFrame::LeftDouble(Point p, dword keyflags) +{ + ToggleMaximize(); + IgnoreMouseUp(); +} + +void TopWindowFrame::MouseMove(Point, dword) +{ + LDUMP(HasWndCapture()); + LDUMP(HasCapture()); + if(!HasCapture() || holding) + return; + Size msz = ComputeClient(minsize).GetSize(); + Point p = GetMousePos() - startpos; + Rect r = startrect; + if(dir.x == -1) + r.left = min(r.left + p.x, startrect.right - msz.cx); + if(dir.x == 1) + r.right = max(r.right + p.x, startrect.left + msz.cx); + if(dir.y == -1) + r.top = min(r.top + p.y, startrect.bottom - msz.cy); + if(dir.y == 1) + r.bottom = max(r.bottom + p.y, startrect.top + msz.cy); + if(dir.y == 0 && dir.x == 0) + r.Offset(p); + SetRect(r); +} + +Image TopWindowFrame::GetDragImage(Point dir) +{ + static Image (*im[9])() = { + Image::SizeTopLeft, Image::SizeLeft, Image::SizeBottomLeft, + Image::SizeTop, Image::Arrow, Image::SizeBottom, + Image::SizeTopRight, Image::SizeRight, Image::SizeBottomRight, + }; + return (*im[(dir.x + 1) * 3 + (dir.y + 1)])(); +} + +Image TopWindowFrame::CursorImage(Point p, dword) +{ + if(!sizeable) + return Image::Arrow(); + return GetDragImage(HasCapture() ? dir : GetDragMode(p)); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Window.cpp b/rainbow/SlaveGui/Window.cpp new file mode 100644 index 000000000..60382f4ed --- /dev/null +++ b/rainbow/SlaveGui/Window.cpp @@ -0,0 +1,53 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +bool SDLWindow::Create(const Rect& rect, const char *title) +{ + win = SDL_CreateWindow(title, rect.left, rect.top, rect.GetWidth(), rect.GetHeight(), + SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL|SDL_WINDOW_BORDERLESS); + if(!win) + return false; + MemoryIgnoreLeaksBegin(); + glcontext = SDL_GL_CreateContext(win); + MemoryIgnoreLeaksEnd(); + if(!glcontext) { + Destroy(); + return false; + } + INTERLOCKED { + static int64 h; + serial = h++; + } + return true; +} + +void SDLWindow::Destroy() +{ + if(glcontext) { + SDL_GL_DeleteContext(glcontext); + glcontext = NULL; + GLDraw::ResetCache(); // TODO: Consider not reseting ALL cache data, only specific context + } + if(win) { + SDL_DestroyWindow(win); + win = NULL; + } +} + +SDLWindow::SDLWindow() +{ + glcontext = NULL; + win = NULL; +} + +SDLWindow::~SDLWindow() +{ + Destroy(); +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGui/Wnd.cpp b/rainbow/SlaveGui/Wnd.cpp new file mode 100644 index 000000000..15253eca9 --- /dev/null +++ b/rainbow/SlaveGui/Wnd.cpp @@ -0,0 +1,540 @@ +#include "Local.h" + +#ifdef GUI_SLAVE + +NAMESPACE_UPP + +#define LLOG(x) LOG(x) +#define LDUMP(x) //DDUMP(x) +#define LDUMPC(x) //DDUMPC(x) +#define LTIMING(x) RTIMING(x) + +Ptr Ctrl::desktop; +Vector Ctrl::topctrl; + +bool Ctrl::invalid; + +bool Ctrl::sdlMouseIsIn; + +Point Ctrl::fbCursorPos = Null; +Image Ctrl::fbCursorImage; +Rect Ctrl::fbCaretRect; +int Ctrl::fbCaretTm; +bool Ctrl::fbEndSession; +int Ctrl::PaintLock; + +bool Ctrl::SystemCursor; + +void Ctrl::SetDesktop(Ctrl& q) +{ + desktop = &q; + desktop->SetOpen(true); + desktop->NewTop(); + invalid = true; +} + +void Ctrl::InitFB() +{ + Ctrl::GlobalBackBuffer(); + Ctrl::InitTimer(); + +// #ifdef PLATFORM_POSIX + SetStdFont(ScreenSans(12)); //FIXME general handling +// #endif + ChStdSkin(); + + static StaticRect x; + x.Color(Cyan()); + SetDesktop(x); +} + +void Ctrl::EndSession() +{ + GuiLock __; + LLOG("Ctrl::EndSession"); + fbEndSession = true; + EndSessionLoopNo = EventLoopNo; +} + +void Ctrl::ExitFB() +{ + TopWindow::ShutdownWindows(); + Ctrl::CloseTopCtrls(); + if(fbEndSession) { + SlaveGuiPtr->Quit(); + #if 0 + SDL_Event event; + event.type = SDL_QUIT; + SDL_PushEvent(&event); + #endif + } +} + +void Ctrl::SetDesktopSize(Size sz) +{ + if(desktop) + desktop->SetRect(sz); + invalid = true; + SyncTopWindows(); +} + +int Ctrl::FindTopCtrl() const +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(this == topctrl[i]) + return i; + return -1; +} + +bool Ctrl::IsAlphaSupported() +{ + return false; +} + +bool Ctrl::IsCompositedGui() +{ + return false; +} + +Vector Ctrl::GetTopCtrls() +{ + Vector ctrl; + if(desktop) + ctrl.Add(desktop); + for(int i = 0; i < topctrl.GetCount(); i++) + if(!dynamic_cast(topctrl[i])) + ctrl.Add(topctrl[i]); + return ctrl; +} + +Ctrl *Ctrl::GetOwner() +{ + GuiLock __; + int q = FindTopCtrl(); + if(q > 0 && topctrl[q]->top) { + Ctrl *x = topctrl[q]->top->owner_window; + LDUMP(Upp::Name(x)); + return dynamic_cast(x) ? x->GetOwner() : x; + } + return NULL; +} + +Ctrl *Ctrl::GetActiveCtrl() +{ + GuiLock __; + return focusCtrl ? focusCtrl->GetTopCtrl() : NULL; +} + +// Vector Ctrl::hotkey; + +int Ctrl::RegisterSystemHotKey(dword key, Function 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() +{ + return SlaveGuiPtr->IsWaitingEvent(); +#if 0 + SDL_PumpEvents(); + SDL_Event events; + return SDL_PeepEvents(&events, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT) > 0; +#endif +} + +void Ctrl::SyncTopWindows() +{ + for(int i = 0; i < topctrl.GetCount(); i++) { + TopWindow *w = dynamic_cast(topctrl[i]); + if(w) + w->SyncRect(); + } +} + +/* +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& inv, const Rect& r) +{ + Rect ri = Null; + for(int j = 0; j < inv.GetCount(); j++) { + Rect rr = inv[j] & r; + if(!rr.IsEmpty()) + ri = IsNull(ri) ? rr : rr | ri; + } + return ri; +} + +void Ctrl::PaintScene(SystemDraw& draw) +{ + if(!desktop) + return; + LLOG("@ DoPaint"); + LTIMING("DoPaint paint"); + draw.Init(screen_size, (uint64)screen.glcontext); + draw.Begin(); + Vector invalid; + invalid.Add(screen_size); + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Rect r = topctrl[i]->GetRect(); + Rect ri = GetClipBound(invalid, r); + if(!IsNull(ri)) { + draw.Clipoff(r); + topctrl[i]->UpdateArea(draw, ri - r.TopLeft()); + draw.End(); + Subtract(invalid, r); + draw.ExcludeClip(r); + } + } + Rect ri = GetClipBound(invalid, desktop->GetRect().GetSize()); + if(!IsNull(ri)) + desktop->UpdateArea(draw, ri); + draw.End(); +} + +void Ctrl::PaintCaretCursor(SystemDraw& draw) +{ + if(!IsNull(fbCaretRect)) + draw.DrawRect(fbCaretRect, InvertColor); + if(sdlMouseIsIn && !SystemCursor) + draw.DrawImage(fbCursorPos.x, fbCursorPos.y, fbCursorImage); +} + +void Ctrl::DoPaint() +{ + if(!PaintLock) { + if(invalid && desktop) { + invalid = false; + SystemDraw draw; + PaintScene(draw); + PaintCaretCursor(draw); + draw.Finish(); + SDL_GL_SwapWindow(screen.win); + } + } +} + +void Ctrl::WndUpdate(const Rect&) +{ + GuiLock __; + Invalidate(); + DoPaint(); +} + +Rect Ctrl::GetWndScreenRect() const +{ + GuiLock __; + return GetRect(); +} + +void Ctrl::WndShow(bool b) +{ + GuiLock __; +} + +void Ctrl::WndUpdate() +{ + GuiLock __; +} + +bool Ctrl::IsWndOpen() const { + GuiLock __; + return FindTopCtrl() >= 0 || this == desktop; +} + +void Ctrl::SetAlpha(byte alpha) +{ + GuiLock __; +} + +Rect Ctrl::GetWorkArea() const +{ + GuiLock __; + return GetVirtualScreenArea(); +} + +void Ctrl::GetWorkArea(Array& rc) +{ + GuiLock __; + Array r; + r.Add(GetVirtualScreenArea()); +} + +Rect Ctrl::GetVirtualWorkArea() +{ + return GetVirtualScreenArea(); +} +/* +Rect Ctrl::GetWorkArea(Point pt) +{ + return GetVirtualScreenArea(); +} +*/ +Rect Ctrl::GetVirtualScreenArea() +{ + GuiLock __; + return desktop ? desktop->GetRect() : Rect(0, 0, 0, 0); +} + +Rect Ctrl::GetPrimaryWorkArea() +{ + return GetVirtualScreenArea(); +} + +Rect Ctrl::GetPrimaryScreenArea() +{ + return GetVirtualScreenArea(); +} + +int Ctrl::GetKbdDelay() +{ + GuiLock __; + return 500; +} + +int Ctrl::GetKbdSpeed() +{ + GuiLock __; + return 1000 / 32; +} + +void Ctrl::DestroyWnd() +{ + for(int i = 0; i < topctrl.GetCount(); i++) + if(topctrl[i]->top && topctrl[i]->top->owner_window == this) + topctrl[i]->WndDestroy(); + int q = FindTopCtrl(); + if(q >= 0) { + Invalidate(); + topctrl.Remove(q); + } + if(top) { + delete top; + top = NULL; + } + isopen = false; + TopWindow *win = dynamic_cast(this); + if(win) + win->DestroyFrame(); +} + +void Ctrl::WndDestroy() +{ + DestroyWnd(); + if(topctrl.GetCount()) + topctrl.Top()->ActivateWnd(); +} + +void Ctrl::PutForeground() +{ + int q = FindTopCtrl(); + if(q >= 0) { + Invalidate(); + topctrl.Remove(q); + topctrl.Add(this); + } + Vector< Ptr > 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]); + for(int i = 0; i < fw.GetCount(); i++) + if(fw[i]) + fw[i]->PutForeground(); +} + +void Ctrl::SetWndForeground() +{ + GuiLock __; + ASSERT(IsOpen()); + if(IsWndForeground()) + return; + Ctrl *to = this; + while(to->top && to->top->owner_window) + to = to->top->owner_window; + to->PutForeground(); + if(this != focusCtrl) + ActivateWnd(); +} + +bool Ctrl::IsWndForeground() const +{ + GuiLock __; + bool b = false; + for(int i = 0; i < topctrl.GetCount(); i++) { + const TopWindow *tw = dynamic_cast(topctrl[i]); + if(tw) + b = tw == this; + } + return b; +} + +void Ctrl::WndEnable(bool) +{ + GuiLock __; +} + +bool Ctrl::SetWndFocus() +{ + GuiLock __; + return true; +} + +bool Ctrl::HasWndFocus() const +{ + GuiLock __; + return focusCtrl && focusCtrl->GetTopCtrl() == this; +} + +bool Ctrl::SetWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::ReleaseWndCapture() +{ + GuiLock __; + ASSERT(IsMainThread()); + return true; +} + +bool Ctrl::HasWndCapture() const +{ + GuiLock __; + return captureCtrl && captureCtrl->GetTopCtrl() == this; +} + +void Ctrl::WndInvalidateRect(const Rect&) +{ + GuiLock __; + Invalidate(); +} + +void Ctrl::WndSetPos(const Rect& rect) +{ + GuiLock __; + TopWindow *w = dynamic_cast(this); + if(w) + w->SyncFrameRect(rect); + Invalidate(); + SetWndRect(rect); +} + +void Ctrl::WndScrollView(const Rect& r, int dx, int dy) +{ + GuiLock __; + LLOG("ScrollView " << rect); + WndInvalidateRect(r); +} + +void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost) +{ + ASSERT(!IsChild() && !IsOpen() && FindTopCtrl() < 0); + NewTop(); + if(owner) { + Ctrl *owner_window = owner->GetTopWindow(); + if(!owner_window) + owner_window = owner->GetTopCtrl(); + ASSERT(owner_window->IsOpen()); + if(owner_window != desktop) { + owner_window->SetForeground(); + top->owner_window = owner_window; + } + } + topctrl.Add(this); + popup = isopen = true; + RefreshLayoutDeep(); + if(activate) SetFocusWnd(); + Invalidate(); +} + +Rect Ctrl::GetDefaultWindowRect() { + GuiLock __; + static int ii = 0; + Rect rect = GetVirtualScreenArea(); + Size sz = rect.GetSize(); + rect.Deflate(sz / 10); + rect.Offset(Size(GetStdFontCy(), 2 * GetStdFontCy()) * (++ii % 8)); + return rect; +} + +Vector SplitCmdLine__(const char *cmd) +{ + Vector out; + while(*cmd) + if((byte)*cmd <= ' ') + cmd++; + else if(*cmd == '\"') { + WString quoted; + while(*++cmd && (*cmd != '\"' || *++cmd == '\"')) + quoted.Cat(FromSystemCharset(String(cmd, 1)).ToWString()); + out.Add(quoted); + } + else { + const char *begin = cmd; + while((byte)*cmd > ' ') + cmd++; + out.Add(String(begin, cmd).ToWString()); + } + return out; +} + +void Ctrl::InstallPanicBox() +{ +} + +void Ctrl::SysEndLoop() +{ +} + +END_UPP_NAMESPACE + +#endif diff --git a/rainbow/SlaveGuiUword/SlaveGuiUword.upp b/rainbow/SlaveGuiUword/SlaveGuiUword.upp new file mode 100644 index 000000000..62d8da907 --- /dev/null +++ b/rainbow/SlaveGuiUword/SlaveGuiUword.upp @@ -0,0 +1,14 @@ +uses + CtrlLib, + RichEdit, + plugin/DroidFonts, + SlaveGui; + +file + main.cpp, + test.qtf, + help.txt; + +mainconfig + "" = "GUI SLAVEGUI"; + diff --git a/rainbow/SlaveGuiUword/help.txt b/rainbow/SlaveGuiUword/help.txt new file mode 100644 index 000000000..3b82933e8 --- /dev/null +++ b/rainbow/SlaveGuiUword/help.txt @@ -0,0 +1,20 @@ +TIMING DoPaint paint : 8.79 s - 15.82 ms ( 8.79 s / 556 ), min: 7.00 ms, max: 69.00 ms, nesting: 1 - 556 + +-------------------------------------- +TIMING PutImage : 678.78 ms - 8.67 us (681.00 ms / 78291 ), min: 0.00 ns, max: 4.00 ms, nesting: 1 - 78291 +TIMING CreateTexture : 45.98 ms - 70.52 us (46.00 ms / 652 ), min: 0.00 ns, max: 6.00 ms, nesting: 1 - 652 +TIMING PutImage colored: 1.35 s - 5.22 us ( 1.36 s / 259617 ), min: 0.00 ns, max: 6.00 ms, nesting: 1 - 259617 +TIMING PutRect : 1.43 s - 26.50 us ( 1.43 s / 53826 ), min: 0.00 ns, max: 21.00 ms, nesting: 1 - 53826 +TIMING DoPaint paint : 4.35 s - 17.27 ms ( 4.35 s / 252 ), min: 9.00 ms, max: 71.00 ms, nesting: 1 - 252 + +---------- COMB_OPT rect ------------- +TIMING PutImage : 787.68 ms - 8.42 us (791.00 ms / 93549 ), min: 0.00 ns, max: 3.00 ms, nesting: 1 - 93549 +TIMING PutImage colored: 1.50 s - 4.80 us ( 1.51 s / 311579 ), min: 0.00 ns, max: 6.00 ms, nesting: 1 - 311579 +TIMING FlushPutRect : 1.58 s - 120.22 us ( 1.58 s / 13147 ), min: 0.00 ns, max: 16.00 ms, nesting: 1 - 13147 +TIMING PutRect : 15.71 ms - 243.65 ns (18.00 ms / 64492 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 64492 +TIMING DoPaint paint : 4.89 s - 16.25 ms ( 4.89 s / 301 ), min: 7.00 ms, max: 71.00 ms, nesting: 1 - 301 + +---------- DIRECT -------------------- +TIMING PutImage : 7.10 s - 11.21 us ( 7.12 s / 632969 ), min: 0.00 ns, max: 21.00 ms, nesting: 1 - 632969 +TIMING PutRect : 65.20 ms - 642.58 ns (68.00 ms / 101472 ), min: 0.00 ns, max: 1.00 ms, nesting: 1 - 101472 +TIMING DoPaint paint : 8.75 s - 18.35 ms ( 8.75 s / 477 ), min: 9.00 ms, max: 61.00 ms, nesting: 1 - 477 diff --git a/rainbow/SlaveGuiUword/main.cpp b/rainbow/SlaveGuiUword/main.cpp new file mode 100644 index 000000000..a358a0a04 --- /dev/null +++ b/rainbow/SlaveGuiUword/main.cpp @@ -0,0 +1,258 @@ +#include +#include + +using namespace Upp; + +#define IMAGECLASS UWordImg +#define IMAGEFILE +#include + +FileSel& UWordFs() +{ + static FileSel fs; + return fs; +} + +class UWord : public TopWindow { +public: + virtual void DragAndDrop(Point, PasteClip& d); + virtual void FrameDragAndDrop(Point, PasteClip& d); + + virtual void ShutdownWindow(); + +protected: + RichEdit editor; + MenuBar menubar; + ToolBar toolbar; + StatusBar statusbar; + String filename; + + static LRUList& lrufile() { static LRUList l; return l; } + + void Load(const String& filename); + void OpenFile(const String& fn); + void New(); + void Open(); + void Save0(); + void Save(); + void SaveAs(); + void Print(); + void About(); + void Destroy(bool shutdown); + void SetBar(); + void FileBar(Bar& bar); + void AboutMenu(Bar& bar); + void MainMenu(Bar& bar); + void MainBar(Bar& bar); + +public: + typedef UWord CLASSNAME; + + static void SerializeApp(Stream& s); + + UWord(); +}; + +void UWord::FileBar(Bar& bar) +{ + bar.Add("New", CtrlImg::new_doc(), THISBACK(New)) + .Key(K_CTRL_N) + .Help("Open new window"); + bar.Add("Open..", CtrlImg::open(), THISBACK(Open)) + .Key(K_CTRL_O) + .Help("Open existing document"); + bar.Add(editor.IsModified(), "Save", CtrlImg::save(), THISBACK(Save)) + .Key(K_CTRL_S) + .Help("Save current document"); + bar.Add("SaveAs", CtrlImg::save_as(), THISBACK(SaveAs)) + .Help("Save current document with a new name"); + bar.ToolGap(); + bar.MenuSeparator(); + bar.Add("Print..", CtrlImg::print(), THISBACK(Print)) + .Key(K_CTRL_P) + .Help("Print document"); + if(bar.IsMenuBar()) { + if(lrufile().GetCount()) + lrufile()(bar, THISBACK(OpenFile)); + bar.Separator(); + bar.Add("Exit", THISBACK1(Destroy, false)); + } +} + +void UWord::AboutMenu(Bar& bar) +{ + bar.Add("About..", THISBACK(About)); +} + +void UWord::MainMenu(Bar& bar) +{ + bar.Add("File", THISBACK(FileBar)); + bar.Add("Window", callback(WindowsMenu)); + bar.Add("Help", THISBACK(AboutMenu)); +} + +void UWord::New() +{ + new UWord; +} + +void UWord::Load(const String& name) +{ + lrufile().NewEntry(name); + editor.SetQTF(LoadFile(name)); + filename = name; + editor.ClearModify(); + Title(filename); +} + +void UWord::OpenFile(const String& fn) +{ + if(filename.IsEmpty() && !editor.IsModified()) + Load(fn); + else + (new UWord)->Load(fn); +} + +void UWord::Open() +{ + FileSel& fs = UWordFs(); + if(fs.ExecuteOpen()) + OpenFile(fs); + else + statusbar.Temporary("Loading aborted."); +} + +void UWord::DragAndDrop(Point, PasteClip& d) +{ + if(AcceptFiles(d)) { + Vector fn = GetFiles(d); + for(int i = 0; i < fn.GetCount(); i++) + if(FileExists(fn[i])) + OpenFile(fn[i]); + } +} + +void UWord::FrameDragAndDrop(Point p, PasteClip& d) +{ + DragAndDrop(p, d); +} + +void UWord::Save0() +{ + lrufile().NewEntry(filename); + if(filename.IsEmpty()) + SaveAs(); + else + if(SaveFile(filename, editor.GetQTF())) { + statusbar.Temporary("File " + filename + " was saved."); + ClearModify(); + } + else + Exclamation("Error saving the file [* " + DeQtf(filename) + "]!"); +} + +void UWord::Save() +{ + if(!editor.IsModified()) return; + Save0(); +} + +void UWord::SaveAs() +{ + FileSel& fs = UWordFs(); + if(fs.ExecuteSaveAs()) { + filename = fs; + Title(filename); + Save0(); + } +} + +void UWord::Print() +{ + editor.Print(); +} + +void UWord::About() +{ + PromptOK("[A5 uWord]&Using [*^www://upp.sf.net^ Ultimate`+`+] technology."); +} + +void UWord::Destroy(bool shutdown) +{ + if(editor.IsModified()) { + switch((shutdown ? PromptYesNo : PromptYesNoCancel)("Do you want to save the changes to the document?")) { + case 1: + Save(); + break; + case -1: + return; + } + } + delete this; +} + +void UWord::ShutdownWindow() +{ + Destroy(true); +} + +void UWord::MainBar(Bar& bar) +{ + FileBar(bar); + bar.Separator(); + editor.DefaultBar(bar); +} + +void UWord::SetBar() +{ + toolbar.Set(THISBACK(MainBar)); +} + +UWord::UWord() +{ + AddFrame(menubar); + AddFrame(TopSeparatorFrame()); + AddFrame(toolbar); + AddFrame(statusbar); + Add(editor.SizePos()); + menubar.Set(THISBACK(MainMenu)); + Sizeable().Zoomable(); + WhenClose = THISBACK1(Destroy, false); + menubar.WhenHelp = toolbar.WhenHelp = statusbar; + static int doc; + Title(Format("Document%d", ++doc)); + Icon(CtrlImg::File()); + editor.ClearModify(); + SetBar(); + editor.WhenRefreshBar = THISBACK(SetBar); + OpenMain(); + ActiveFocus(editor); + + editor <<= LoadFile(GetDataFile("test.qtf")); +} + +void UWord::SerializeApp(Stream& s) +{ + int version = 1; + s / version; + s % UWordFs(); + if(version >= 1) + s % lrufile(); +} + +GUI_APP_MAIN +{ + Ctrl::SystemCursor = true; + + SetLanguage(LNG_ENGLISH); + SetDefaultCharset(CHARSET_UTF8); + + UWordFs().Type("QTF files", "*.qtf") + .AllFilesType() + .DefaultExt("qtf"); + + LoadFromFile(callback(UWord::SerializeApp)); + UWord uword; + Ctrl::EventLoop(); + StoreToFile(callback(UWord::SerializeApp)); +} diff --git a/rainbow/SlaveGuiUword/test.cpp b/rainbow/SlaveGuiUword/test.cpp new file mode 100644 index 000000000..8437a52ed --- /dev/null +++ b/rainbow/SlaveGuiUword/test.cpp @@ -0,0 +1,5 @@ +#include + +#include + +void Foo() {} \ No newline at end of file diff --git a/rainbow/SlaveGuiUword/test.qtf b/rainbow/SlaveGuiUword/test.qtf new file mode 100644 index 000000000..c4fe64413 --- /dev/null +++ b/rainbow/SlaveGuiUword/test.qtf @@ -0,0 +1,2998 @@ +[ $$0,0#00000000000000000000000000000000:Default] +[{_} +[s0;2 &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 ArrayCtrl]]}}&] +[s0;i448;a25;kO9;2 &] +[s0; &] +[s0;*@3 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:class: [@(0.0.255) class]_[* ArrayCtrl]_:_[@(0.0.255) public +]_[*@3 Ctrl]&] +[s0;i448;a25;kKO9;2 &] +[s0;* &] +[s0;* &] +[s0; [* ArrayCtrl] implements basic grid functionality. It is typically +used for display and editing of arrays of values or (heterogeneous) +records. The records correspond to rows in the array, the individual +fields within each record can be either bound to columns or to +any generic [* Ctrl]`'s, thus supporting basic master`-detail functionality +with practically no additional cost.&] +[s0; &] +[s0; The standard derived classes extend various aspects of the ArrayCtrl +functionality. [* SqlArray] adds the nuts and bolts needed for +editing SQL`-based tables, whereas [* PopupTable] couples the ArrayCtrl +functionality with the drop`-down mechanism very similar to the +one used in popup menus. This opens the door for implementing +drop`-down controls like [* DropList] (aka [/ combo box]) or [* DropChoice] +(usually used together with a control of the [* EditField ]or [* DataPusher] +family to support coupling native data editing with drop`-down +selection, widely used for history or commonly used predefined +values. The [* ArrayPair] is, as its name implies, a pair of [* ArrayCtrl]`'s +with arrow buttons between them allowing to visually select subsets +of a certain set by moving its elements between the two lists.&] +[s0; &] +[s0; [*+117 The array data organization: indices and columns]&] +[s0; &] +[s0; There is a great deal of genericity supported by the ArrayCtrl +with respect both to its source data and its visual presentation. +Conceptually, the source array data is a matrix of [* Value]`'s. +There is a series of methods for accessing this source data, +the basic ones being [* Set] and [* Get]. The rows are addressed +by integer indices (zero based), the columns can be addressed +either by integer indices as well, or alternatively any source +column can be assigned an [* Id] identifier and addressed by it. +This is especially helpful in SQL`-based tables, where the table +column names can be used for the [* Id]`'s. A pair of methods, +[* GetPos] and [* GetId], can be used to translate these two column +addressing modes. In the code terminology, the columns in the +source data matrix are called [/ indices] whereas the visual (output) +columns are called simply [/ columns].&] +[s0; &] +[s0; The visual ArrayCtrl structure can be entirely independent of +the source data structure (although it`'s seldom helpful to make +the mapping completely arbitrary). Basically, each column can +have an arbitrary number of indices defining its source data. +Of course, the most common case is one index per column. This +is also simplest to address, because the column indices are equal +to the source data indices. However, many other combinations +are possible, each of which can be handy in certain situations:&] +[s0; &] +[s0;i150;O0; Index without a column: the most common of the `"special`" +cases is used mainly for row id`'s or other internally important +data without visual representation. The same behaviour can be +obtained by making a column invisible.&] +[s0;i150;O0; Column without an index (a [/ rownum column]): this less +common case can be used to display external data (not stored +in the table). &] +[s0;i150;O0; Multiple columns sharing the same index: this can be +used to display various aspects of a complex data object or to +display the same source data in multiple ways (e.g., a temperature +reading in Celsius and Fahrenheit degrees).&] +[s0;i150;O0; Column with multiple indices: can be used to display +information gathered from multiple source data columns. This +is used for instance in IconDes in TheIDE to display image identifiers +together with their sizes in the list. This is the most complicated +case because you have to implement a specific [* Display] for such +a multi`-index column.&] +[s0; &] +[s0; [* Note:] in the current U`+`+ version, the implementation of index`-less +columns (arrays with external data not stored in the source matrix) +is rather awkward. It is planned to enhance this feature in the +future by adding support for access to external data via a data +accessor interface object. &] +[s0; &] +[s0; [*+117 ArrayCtrl GUI: selection, editing, and local menu]&] +[s0; &] +[s0; Array rows can be selected using the mouse or keyboard. ArrayCtrl`'s +support both single`-selection (plain cursor) and multiselection +model. Of course, row selection can be controlled via the programmatic +array interface as well. The selection and cursor always spans +entire rows, it is not possible (without substantial patchwork) +to select only certain columns or individual cells.&] +[s0; &] +[s0; The ArrayCtrl rows can be inserted, edited and deleted either +programmatically, or via common GUI elements (mouse and keyboard +selection, local menu). It is possible to alter the standard +ArrayCtrl local menu using the [* WhenBar] callback.&] +[s0; &] +[s0; [* Note:] it is worth noting that the standard editing keys ([* Insert] +`= row insertion, [* Ctrl`+Enter] `= editing and [* Ctrl`+Delete] +`= deletion) are not hardcoded in the ArrayCtrl`'s [* Key] method, +they are mere hotkeys for the relevant local menu items. When +you change the ArrayCtrl`'s local menu, the editing hotkeys change +accordingly.&] +[s0; &] +[s0; A special but rather important case of array editing is [/ sorting]: +there is no specific standard GUI for that. If you aren`'t content +with programmatic sorting (e.g. after opening a dialog or after +loading the array data), you have to implement some GUI for that +as well. In certain cases, it is cool to use the [* HeaderCtrl] +[* WhenAction] method to allow sorting the array by clicking on +the header columns; alternatively you can add a sort function +to the array local menu or possibly somewhere else (like a standalone +button in the dialog).&] +[s0; &] +[s0; [* Insertion tricks: before, after, and the secrets of the AppendLine]&] +[s0; &] +[s0; In todays text editors, when you type a new letter, it is trivial +to see where in the text will the new letter go. This is so because +the caret is always positioned between a pair of successive letters +and thus is well defines the insertion spot. Additionally, the +caret can be placed in front of the first letter or after the +last letter, which naturally allows typing some text at the very +beginning or end.&] +[s0; &] +[s0; When inserting new rows into the array controls, things are +a bit more tricky. This is so because, unlike in the text editor, +the cursor is not placed [/ between] two successive rows, but [/ over] +a certain row. This is of course necessary to make row editing +possible (note that in the aforementioned text editor analogy, +a single letter is an atomic object whereas in the array it is +a potentially complex structure consisting of many columns and +data items). However, when it comes to row insertion, it has +two main troubles as its implication:&] +[s0; &] +[s0;i150;O9; [* 1.]-|It is necessary to decide somehow whether the new +row will go [/ above] or [/ below] the cursor row.&] +[s0;i150;O9; [* 2.]-|In an array with [/ n] rows, there are [/ n`+1] possible +locations for a new row (before the row #0, #1 ... #([/ n`-1]) +and after the last row), but only [/ n] distinct cursor locations.&] +[s0; &] +[s0; Over the years, during the development of U`+`+, we experimented +with multiple ways to overcome these logical problems. As a result +of this, the ArrayCtrl supports a few methods allowing to fine`-tune +the row insertion mechanism. It is also worth noting that there +are cases, like in the case of SQL`-based tables, where the row +ordering is arbitrary or implicit and the exact `'location`' +of a new row doesn`'t make any sense. In such cases, it is possible +to replace array [/ insertion] function with the [/ append] function +emphasizing the fact that the visual row order is unimportant +and that insertion means merely adding a new record to the record +set.&] +[s0; &] +[s0; For arrays in which the order is important, there are two ways +to solve the [/ n`+1] row positions dilemma:&] +[s0; &] +[s0;i150;O9; [* 1.]-|Replacing the Insert function with a pair of functions +for inserting a new row [/ before] / [/ after] the current row.&] +[s0;i150;O9; [* 2.]-|Visually extending the array by adding a pseudo`-row +with no real data at its end; this creates the [/ n`+1]`-th cursor +position necessary to denote all the available row insertion +locations.&] +[s0; &] +[s0; In the first case, it is also possible to select which of the +insertion functions (before / after) takes precedence (which +of the two actions should be bound to the standard [* Insert] hotkey). +This corresponds to the [* BeforeAfterInserting] and [* AfterBeforeInserting] +methods. The second case is called the [* AppendLine] and is activated +by setting the property with the same name.&] +[s0; &] +[s0; To make all this even more interesting, a special mechanism +called [* InsertAppend] is available to make array filling as easy +as possible. When activated and the user appends a new row at +the table end, after pressing [* Enter] (to commit the inserted +row) another row is automatically added after it and opened for +editing. This mechanism is turned on by default, but it can be +disable by setting the [* NoInsertAppend] property to true.&] +[s0;0 &] +[s0; &] +[s0; &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 Categorized method summary]]}}&] +[s0;b42; [2 The following table summarizes ArrayCtrl methods according +to the aspect of functionality they support together with a very +brief description. For more thorough documentation of the individual +methods see below.]&] +[s0; &] +[ {{2337:7663-1 [s0; [* Initialization and configuration]] +:: [s0; ] +:: [s0; Reset] +:: [s0; clears column `& index definition and restores all ArrayCtrl +default properties] +:: [s0; IsEdit] +:: [s0; true `= array state automaton is currently in row editing mode] +:: [s0; IsInsert] +:: [s0; true `= array state automaton is currently in row insertion +mode] +:: [s0; SetLineCy] +:: [s0; sets array row height (global or individual for a single row)] +:: [s0; GetLineCy] +:: [s0; returns logical array row height (value set by preceding SetLineCy)] +:: [s0; GetLineY] +:: [s0; returns [/ y] position of given row (relative to table beginning)] +:: [s0; `[No`]AppendLine] +:: [s0; `[do not`] display an additional pseudo`-row used for row insertion] +:: [s0; IsAppendLine] +:: [s0; returns actual value of the [* AppendLine] property] +:: [s0; ShowAppendLine] +:: [s0; scrolls the table view to display the appending line] +:: [s0; `[No`]Inserting] +:: [s0; `[do not`] allow inserting new rows] +:: [s0; IsInserting] +:: [s0; returns actual value of the [* Inserting] property] +:: [s0; BeforeAfterInserting] +:: [s0; allow inserting rows before / after current row (default `= +before)] +:: [s0; AfterBeforeInserting] +:: [s0; allow inserting rows before / after current row (default `= +after)] +:: [s0; NoInsertAppend] +:: [s0; do not autoinsert another row after committing last row insertion] +:: [s0; IsEditing] +:: [s0; true `= (at least one column of the) ArrayCtrl supports editing] +:: [s0; `[No`]Duplicating] +:: [s0; `[do not`] allow row duplication] +:: [s0; IsDuplicating] +:: [s0; returns actual value of the [* Duplicating] property] +:: [s0; Appending] +:: [s0; allow appending new row at the table end] +:: [s0; IsAppending] +:: [s0; returns actual state of the [* Appending] property] +:: [s0; AutoAppending] +:: [s0; allow appending new row at the table end, Enter appends another +one] +:: [s0; IsAutoAppending] +:: [s0; returns actual state of [* AutoAppending] property] +:: [s0; `[No`]Removing] +:: [s0; `[do not`] allow table row removing] +:: [s0; IsRemoving] +:: [s0; returns actual state of the [* Removing] property] +:: [s0; `[No`]AskRemove] +:: [s0; `[do not`] prompt user to confirm row removal] +:: [s0; IsAskRemove] +:: [s0; returns actual state of the [* AskRemove] property] +:: [s0; Moving] +:: [s0; allow row swapping (moving a row before / after neighbouring +row)] +:: [s0; IsMoving] +:: [s0; returns actual state of the [* Moving] property] +:: [s0; `[No`]Header] +:: [s0; `[do not`] display table header] +:: [s0; `[No`]Track] +:: [s0; `[do not`] animate tracking table column widths] +:: [s0; `[No`]VertGrid] +:: [s0; `[do not`] display column breaks] +:: [s0; `[No`]HorzGrid] +:: [s0; `[do not`] display row breaks] +:: [s0; `[No`]Grid] +:: [s0; `[do not`] display both grids (VertGrid `+ HorzGrid)] +:: [s0; GridColor] +:: [s0; set grid line color] +:: [s0; EvenRowColor] +:: [s0; background color for even rows] +:: [s0; OddRowColor] +:: [s0; background color for odd rows] +:: [s0; RowFormat] +:: [s0; formats menu items substituting given word for the term `'row`'] +:: [s0; RowName] +:: [s0; sets the context`-relevant word to substitute for `'row`' in +the local menu texts] +:: [s0; NoCursor] +:: [s0; do not highlight cursor row] +:: [s0; `[No`]MouseMoveCursor] +:: [s0; automatically move cursor as the mouse moves (used e.g. in PopupTable)] +:: [s0; `[No`]AutoHideSb] +:: [s0; `[do not`] display scroll bar only when necessary] +:: [s0; MultiSelect] +:: [s0; enable selecting multiple rows at the same time] +:: [s0; ColumnWidths] +:: [s0; sets logical column widths using a formatted string, e.g. `"1 +5 10 10 5 1`"]}}&] +[s0; &] +[ {{2337:7663-1 [s0; [* Array index `& column structure management]] +:: [s0; ] +:: [s0; IndexInfo] +:: [s0; returns the [* IdInfo] structure describing an index (see below)] +:: [s0; AddIndex] +:: [s0; adds a new index to the source data matrix] +:: [s0; GetIndexCount] +:: [s0; returns number of index columns (columns in the source data +matrix)] +:: [s0; GetId] +:: [s0; returns identifier of a given index (given by its integral index)] +:: [s0; GetPos] +:: [s0; returns integral index of source matrix column ([/ index]) identified +by an [* Id]] +:: [s0; SetId] +:: [s0; sets the [* Id] identifier for a given index (column of the source +matrix)] +:: [s0; AddKey] +:: [s0; sets up the first index to act as primary key (often used for +SQL tables)] +:: [s0; GetKeyId] +:: [s0; returns primary key identifier (equal to [* GetId(0)])] +:: [s0; AddColumn] +:: [s0; adds a column`-index pair to the table (one data column, one +output column)] +:: [s0; AddColumnAt] +:: [s0; adds a column bound to a given index] +:: [s0; AddRowNumColumn] +:: [s0; adds a column without an index (used for external data)] +:: [s0; GetColumnCount] +:: [s0; returns number of (visual) columns in the table] +:: [s0; FindColumnWithPos] +:: [s0; locates table column according to given index number] +:: [s0; FindColumnWithId] +:: [s0; locates table column according to index identifier] +:: [s0; ColumnAt] +:: [s0; returns the [* ArrayCtrl`::Column] structure describing given column] +:: [s0; HeaderTab] +:: [s0; returns the [* HeaderCtrl`::Column] structure for the given column] +:: [s0; HeaderObject] +:: [s0; returns a reference to the [* HeaderCtrl] object for this table] +:: [s0; SerializeHeader] +:: [s0; serialize header layout information (column widths etc.)] +:: [s0; AddCtrl] +:: [s0; adds an outer control`-index pair to the table (one data column, +one outer Ctrl)] +:: [s0; AddCtrlAt] +:: [s0; adds an outer control bound to a given index] +:: [s0; AddRowNumCtrl] +:: [s0; adds an outer control without an index `- used ([/ seldom]) for +external data] +:: [s0; SetDisplay] +:: [s0; sets display for a given table column or cell] +:: [s0; GetDisplay] +:: [s0; returns column / cell display] +:: [s0; SetCtrl] +:: [s0; sets a [* Ctrl] object for custom editing of a given cell] +:: [s0; GetTotalCy] +:: [s0; returns total row height] +:: [s0; GetLineAt] +:: [s0; locate table row when given an [/ y] position (relative to table +top)] +:: [s0; GetClickColumn] +:: [s0; returns column number of last clicked column (Null if clicked +outside existing rows)] +:: [s0; GetClickRow] +:: [s0; returns row number of last clicked row (Null if clicked outside +existing rows)] +:: [s0; GetClickPos] +:: [s0; returns Point(GetClickColumn(), GetClickRow())]}}&] +[s0; &] +[ {{2337:7663-1 [s0; [* Data setting `& retrieval]] +:: [s0; ] +:: [s0; SetCount] +:: [s0; sets number of rows in the array] +:: [s0; SetVirtualCount] +:: [s0; sets number of rows in the array with external data] +:: [s0; GetCount] +:: [s0; returns number of rows] +:: [s0; Clear] +:: [s0; clears array data, identical to [* SetCount(0)]] +:: [s0; Shrink] +:: [s0; shrinks source data matrix to the minimum necessary size] +:: [s0; Get] +:: [s0; returns given Value element of the source data matrix] +:: [s0; GetOriginal] +:: [s0; returns given element of source data matrix before editing] +:: [s0; Set] +:: [s0; sets given element of the source data matrix] +:: [s0; GetKey] +:: [s0; returns given primary key (column #0 in the data matrix)] +:: [s0; GetOriginalKey] +:: [s0; returns `'old`' value of primary key before editing] +:: [s0; GetColumn] +:: [s0; returns value of a given output column (according to its index +mapping)] +:: [s0; GetConvertedColumn] +:: [s0; returns value of a given output column after applying its [* Convert]] +:: [s0; ReadRow] +:: [s0; returns a row of the source data matrix] +:: [s0; Add] +:: [s0; adds a new row at the end of table] +:: [s0; Insert] +:: [s0; inserts a new row into the table] +:: [s0; Remove] +:: [s0; removes a given table row] +:: [s0; SwapUp] +:: [s0; exchanges a table row with the preceding row] +:: [s0; SwapDown] +:: [s0; exchanges a table row with the next row] +:: [s0; Sort] +:: [s0; sorts table rows using a given predicate] +:: [s0; ClearCache] +:: [s0; clears data conversion cache] +:: [s0; InvalidateCache] +:: [s0; invalidates given table row in the conversion cache]}}&] +[s0; &] +[ {{2337:7663-1 [s0; [* Cursor `& selection management]] +:: [s0; ] +:: [s0; GetSelectCount] +:: [s0; returns number of currently selected rows] +:: [s0; IsSelection] +:: [s0; checks whether any rows are selected (identical to [* GetSelectCount() +> 0])] +:: [s0; Select] +:: [s0; selects / unselects given row or a series of rows] +:: [s0; IsSelected] +:: [s0; checks whether given row is selected] +:: [s0; ClearSelection] +:: [s0; clears the current selection] +:: [s0; SetCursor] +:: [s0; moves array cursor to a new row] +:: [s0; KillCursor] +:: [s0; removes the cursor away from the table] +:: [s0; CancelCursor] +:: [s0; cancels editing of current row] +:: [s0; IsCursor] +:: [s0; checks whether cursor is in the table (identical to [* GetCursor() +>`= 0])] +:: [s0; GetCursor] +:: [s0; returns current cursor row, `-1 when none] +:: [s0; GoBegin] +:: [s0; moves the cursor to the first table row] +:: [s0; GoEnd] +:: [s0; moves the cursor to the last table row] +:: [s0; GetCursorSc] +:: [s0; returns the location of the cursor row within the table view +area] +:: [s0; ScCursor] +:: [s0; scrolls the table to move the cursor row to given location within +the table view] +:: [s0; CenterCursor] +:: [s0; scrolls the table to move cursor into the middle of the current +view] +:: [s0; ScrollInto] +:: [s0; scrolls the table by minimum amount necessary to make given +row visible] +:: [s0; ScrollIntoCursor] +:: [s0; scrolls the table by minimum amount necessary to make cursor +row visible] +:: [s0; GetScroll] +:: [s0; returns current table scrollbar location] +:: [s0; ScrollTo] +:: [s0; sets table scrollbar location] +:: [s0; Find] +:: [s0; locates table row containing a given element] +:: [s0; FindSetCursor] +:: [s0; moves the cursor to table row containing a given element]}}&] +[s0; &] +[s0; &] +[s0; &] +[ {{2337:7663-1 [s0; [* GUI elements]] +:: [s0; ] +:: [s0; StdBar] +:: [s0; the default array local menu] +:: [s0; IsModified] +:: [s0; checks modification state of given array cell] +:: [s0; StartEdit] +:: [s0; open current array row for editing] +:: [s0; GetEditColumn] +:: [s0; returns the column being currently edited] +:: [s0; DoEdit] +:: [s0; corresponds to the local menu `'Edit`' function] +:: [s0; DoInsert] +:: [s0; corresponds to the local menu `'Insert`' function] +:: [s0; DoInsertBefore] +:: [s0; corresponds to the local menu `'Insert before`' function] +:: [s0; DoInsertAfter] +:: [s0; corresponds to the local menu `'Insert after`' function] +:: [s0; DoAppend] +:: [s0; corresponds to the local menu `'Append`' function] +:: [s0; DoRemove] +:: [s0; corresponds to the local menu `'Remove`' function] +:: [s0; DoDuplicate] +:: [s0; corresponds to the local menu `'Duplicate`' function] +:: [s0; DoSelectAll] +:: [s0; selects the entire array] +:: [s0; AcceptEnter] +:: [s0; commits the currently edited row and possibly begins insertion +of another row]}}&] +[s0; &] +[ {{2337:7663-1 [s0; [* Notification callbacks]] +:: [s0; ] +:: [s0; WhenLeftClick] +:: [s0; left mouse click within the array] +:: [s0; WhenLeftDouble] +:: [s0; left mouse doubleclick within the array] +:: [s0; WhenSel] +:: [s0; called when cursor or selection status of widget changes] +:: [s0; WhenCursor] +:: [s0; called whenever the cursor location changes [/ (deprecated, use +WhenSel)]] +:: [s0; WhenKillCursor] +:: [s0; called when the cursor moves away from the table [/ (deprecated, +use WhenSel)]] +:: [s0; WhenSelection] +:: [s0; called whenever current selection changes [/ (deprecated, use +WhenSel)]] +:: [s0; WhenEnterRow] +:: [s0; called whenever the cursor moves to a new row [/ (deprecated, +use WhenSel)]] +:: [s0; WhenUpdateRow] +:: [s0; called after updating a row] +:: [s0; WhenAcceptRow] +:: [s0; additional row validation callback] +:: [s0; WhenStartEdit] +:: [s0; called after initiating row editing] +:: [s0; WhenAcceptEdit] +:: [s0; called after accepting changes to a given row] +:: [s0; WhenArrayAction] +:: [s0; called whenever array source data changes (after insert / delete +/ edit)] +:: [s0; WhenBar] +:: [s0; can be used to supply custom local menu for the array] +:: [s0; WhenCtrlsAction] +:: [s0; called by [* WhenAction] callbacks of internally created controls]}}&] +[s0;0 &] +[s0; &] +[s0; &] +[s0; &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 Detailed method description]]}}&] +[s0; &] +[s0; [* Initialization and configuration]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Reset`(`): [@(0.0.255)2 void][2 _][*2 Reset][2 ()]&] +[s0;l288; [2 Clears table rows and resets all array properties to their +default values.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ShowAppendLine`(`): [@(0.0.255)2 void][2 _][*2 ShowAppendLi +ne][2 ()]&] +[s0;l288; [2 Show an additional pseudo`-row at the table end. When +clicked, a new row is appended to the array.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsEdit`(`)const: [@(0.0.255)2 bool][2 _][*2 IsEdit][2 ()_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Checks whether the array is currently being edited.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= a +row is currently open for editing, ][*2 false][2 `= array is in +normal browsing mode]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsInsert`(`)const: [@(0.0.255)2 bool][2 _][*2 IsInsert][2 ()_ +][@(0.0.255)2 const]&] +[s0;l288; [2 Checks whether a new row is currently being inserted.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= newly +inserted row is currently being edited, ][*2 false][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetLineCy`(int`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 SetLineCy][2 (][@(0.0.255)2 int][2 _][*@3;2 cy][2 )]&] +[s0;l288; [2 Sets the (default) array row height. For certain rows, +this can be overriden by the two`-parameter version of this method.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 cy][2 -|row height in pixels]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetLineCy`(int`,int`): [@(0.0.255)2 void][2 _][*2 SetLineCy +][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 cy][2 )]&] +[s0;l288; [2 Sets row height for a given row. This overrides the default +value set by the one`-parameter version of this method.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|row index (zero based)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 cy][2 -|row height in pixels, +][*2 Null][2 `= use default row height]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetLineCy`(`)const: [@(0.0.255)2 int][2 _][*2 GetLineCy][2 () +_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns default array row height.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|row height in pixels]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetLineY`(int`)const: [@(0.0.255)2 int][2 _][*2 GetLineY][2 ( +][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns ][/2 y][2 position of given array row (the pixel +distance between the top of first array row and ][/2 i][2 `-th row, +i.e. sum of heights of all rows above this row).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|row index (zero based)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|Vertical position +of row top in pixels (relative to array beginning)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetLineCy`(int`)const: [@(0.0.255)2 int][2 _][*2 GetLineCy][2 ( +][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the height of a given row (either the row`-specific +row height, or, when Null, the default row height).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|row index (zero based)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|row height in pixels]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AppendLine`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AppendLine][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 The AppendLine property controls whether the array displays +an additional `'append`' row after its last (real) row. ]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= display appending +row, ][*2 false][2 `= hide it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoAppendLine`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoAppendLine][2 ()]&] +[s0;l288; [2 Hide the appending line (identical to ][*2 AppendLine(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsAppendLine`(`)const: [@(0.0.255)2 bool][2 _][*2 IsAppendL +ine][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 AppendLine][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= display +appending pseudo`-row at the end of the array]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Inserting`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 Inserting][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable inserting new rows in the array (no matter +which insertion mechanism is selected).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= enable insertion, +][*2 false][2 `= disable it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoInserting`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoInserting][2 ()]&] +[s0;l288; [2 Disables row insertion (identical to ][*2 Inserting(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsInserting`(`)const: [@(0.0.255)2 bool][2 _][*2 IsInsertin +g][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 Inserting][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row +insertion is enabled, ][*2 false][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Appending`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 Appending][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable adding new rows at the table end.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= enable row +appending, ][*2 false][2 `= disable it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsAppending`(`)const: [@(0.0.255)2 bool][2 _][*2 IsAppendin +g][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 Appending][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= appending +rows is enabled, ][*2 false][2 when not.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AutoAppending`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AutoAppending][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Same as ][*2 Appending][2 but Enter pressed when editing +a new row accepts it and adds another one at the table end.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true ][2 to enable the +mode]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsAutoAppending`(`)const: [@(0.0.255)2 bool][2 _][*2 IsAuto +Appending][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of ][*2 AutoAppending][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= ][*2 AutoAppending +][2 is active]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:BeforeAfterInserting`(int`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 BeforeAfterInserting][2 (][@(0.0.255)2 int][2 _][*@3;2 q][2 _`=_][@3;2 1][2 )]&] +[s0;l288; [2 Activate before / after row insertion mechanism (][*2 Insert][2 +hotkey `= before).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AfterBeforeInserting`(int`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AfterBeforeInserting][2 (][@(0.0.255)2 int][2 _][*@3;2 q][2 _`=_][@3;2 2][2 )]&] +[s0;l288; [2 Activate before / after row insertion mechanism (][*2 Insert][2 +hotkey `= after)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Duplicating`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 Duplicating][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable row duplication. Note that this property +only controls whether the `'Duplicate`' item should be present +in the array local menu. Of course, nothing can prevent you from +supporting duplication in some other way, or from calling the +][*2 DoDuplicate][2 method as you see fit.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= enable duplication, +][*2 false][2 `= disable it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoDuplicating`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoDuplicating][2 ()]&] +[s0;l288; [2 Disable row duplication (identical to ][*2 Duplicating(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsDuplicating`(`)const: [@(0.0.255)2 bool][2 _][*2 IsDuplic +ating][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the state of the ][*2 Duplicating][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= local +menu offers row duplication, ][*2 false][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoInsertAppend`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoInsertAppend][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enables / disables the auto`-append mechanism (see above +section on inserting rows).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= disable InsertAppend +mechanism, ][*2 false][2 `= enable it (the default)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsEditing`(`)const: [@(0.0.255)2 bool][2 _][*2 IsEditing][2 ( +)_][@(0.0.255)2 const]&] +[s0;l288; [2 Checks whether at least one array column supports editing +(whether it is possible to ][/2 open][2 a row for editing).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row +editing is possible, ][*2 false][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Removing`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 Removing][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable deleting rows from the table.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= enable deletion, +][*2 false][2 `= disable it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoRemoving`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 NoRemoving][2 ()]&] +[s0;l288; [2 Disable deleting table rows (identical to ][*2 Removing(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsRemoving`(`)const: [@(0.0.255)2 bool][2 _][*2 IsRemoving][2 ( +)_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 Removing][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row +deletion is enabled, ][*2 false ][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AskRemove`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AskRemove][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Sets whether the user must manually confirm array row +deletion. When set to ][*2 true][2 , every time a row is to be deleted, +a confirmation dialog pops up. When set to ][*2 false][2 , rows are +deleted automatically without any further confirmation.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= prompt user +to confirm row deletion, ][*2 false][2 `= delete rows instantly]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoAskRemove`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoAskRemove][2 ()]&] +[s0;l288; [2 Disables user confirmation of row deletion (equivalent +to ][*2 AskRemove(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsAskRemove`(`)const: [@(0.0.255)2 bool][2 _][*2 IsAskRemov +e][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 AskRemove][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= user +confirmation is needed to delete rows, ][*2 false][2 `= rows are +deleted immediately]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Moving`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 Moving][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable row swapping. When set to ][*2 true][2 , +it is possible to move an array row up and down by swapping it +with the previous / next row. This can be used to reorder array +rows in a visually straightforward manner.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= offer row +moving in the local menu, ][*2 false][2 `= don`'t]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsMoving`(`)const: [@(0.0.255)2 bool][2 _][*2 IsMoving][2 ()_ +][@(0.0.255)2 const]&] +[s0;l288; [2 Returns current state of the ][*2 Moving][2 property.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= local +menu supports row swapping, ][*2 false][2 `= it doesn`'t]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Header`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 Header][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Show / hide the ][*^topic`:`/`/CtrlLib`/src`/HeaderCtrl`$en`-us^2 HeaderCtrl +][2 object for this table.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= show table +header, ][*2 false][2 `= hide it]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoHeader`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 NoHeader][2 ()]&] +[s0;l288; [2 Hide table header (equivalent to ][*2 Header(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Track`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 Track][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Animate array column resizing. This is equivalent to setting +the ][*^topic`:`/`/CtrlLib`/src`/HeaderCtrl`$en`-us`#`:`:HeaderCtrl`:`:Track`(bool`)^2 T +rack][2 property in the array HeaderCtrl.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= repaint the +array repeatedly while dragging column widths, ][*2 false][2 `= +regenerate everything only after drag `& drop is finished.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoTrack`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _][*2 N +oTrack][2 ()]&] +[s0;l288; [2 Do not animate array column resizing (equivalent to ][*2 Track(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:VertGrid`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 VertGrid][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Show / hide vertical array grid lines (separating array +columns).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= show vertical +grid lines, ][*2 false][2 `= hide them]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoVertGrid`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 NoVertGrid][2 ()]&] +[s0;l288; [2 Hide vertical grid lines (equivalent to ][*2 VertGrid(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HorzGrid`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 HorzGrid][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Show / hide horizontal grid lines (separating array rows).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= show horizontal +grid lines, ][*2 false][2 `= hide them]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoHorzGrid`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 NoHorzGrid][2 ()]&] +[s0;l288; [2 Hide horizontal grid lines (equivalent to ][*2 HorzGrid(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Grid`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 Grid][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Show / hide both horizontal and vertical grid lines (equivalent +to ][*2 HorzGrid(b).VertGrid(b)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= show grid +line matrix, ][*2 false][2 `= hide all grid lines]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoGrid`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _][*2 N +oGrid][2 ()]&] +[s0;l288; [2 Hide horizontal and vertical grid lines (equivalent to +][*2 Grid(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GridColor`(Color`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 GridColor][2 (][_^Color^2 Color][2 _][*@3;2 c][2 )]&] +[s0;l288; [2 Sets the color for grid lines.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 c][2 -|new grid line color]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:EvenRowColor`(Color`,Color`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 EvenRowColor][2 (][_^Color^2 Color][2 _][*@3;2 paper][2 _`=_Blend(SColorMark, +SColorPaper, ][@3;2 220][2 ), ][_^Color^2 Color][2 _][*@3;2 ink][2 _`=_SColorText)]&] +[s0;l288; [2 Sets the paper and ink (background and foreground) color +for even array rows. In certain cases setting a different background +color for odd and even rows helps to simplify visual orientation +in the arrays (especially when the array has many columns).]&] +[s0;l288; [*2 Note:][2 the even / odd row terminology refers to the natural +array row numbering, so first array row is ][/2 odd][2 and the second +is ][/2 even][2 . This is in contrast to the zero`-baesd integral +row indexing, where the first array row has index 0.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 paper][2 -|background color to +use for second, fourth, sixth etc. array row]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ink][2 -|foreground color for +even rows]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:OddRowColor`(Color`,Color`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 OddRowColor][2 (][_^Color^2 Color][2 _][*@3;2 paper][2 _`=_SColorInfo, +][_^Color^2 Color][2 _][*@3;2 ink][2 _`=_SColorText)]&] +[s0;l288; [2 Sets the paper and ink (background and foreground) color +for odd array rows.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 paper][2 -|background color to +use for first, third, fifth etc. array row]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ink][2 -|foreground color for +odd rows]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoCursor`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoCursor][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Turns on / off highlighting cursor row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= do not highlight +cursor row, ][*2 false][2 `= default behaviour (cursor row is shown +in inverse colors)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:MouseMoveCursor`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 MouseMoveCursor][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enables / disables automatical cursor row switching as +the mouse cursor moves over the array rows.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= automatically +switch cursor row, ][*2 false][2 `= only upon clicks and keyboard +navigation]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoMouseMoveCursor`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoMouseMoveCursor][2 ()]&] +[s0;l288; [2 Disable automatical cursor row switching (equivalent to +][*2 MouseMoveCursor(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AutoHideSb`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AutoHideSb][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 When set to ][*2 true][2 , the vertical scrollbar at the right +array edge is displayed only when the total row height exceeds +the array view height. When set to ][*2 false][2 , the scrollbar +is shown all the time.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= show / hide +the scrollbar as necessary, ][*2 false][2 `= display it unconditionally]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoAutoHideSb`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoAutoHideSb][2 ()]&] +[s0;l288; [2 Display vertical scrollbar all the time (equivalent to +][*2 AutoHideSb(false)][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HideSb`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 HideSb][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Hides vertical scrollbar (even if it would be needed).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AutoHideHorzSb`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 AutoHideHorzSb][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Makes horizontal scroll bar (active if HeaderCtrl is in +absolute mode only) to autohide. Default is on.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoAutoHideHorzSb`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoAutoHideHorzSb][2 ()]&] +[s0;l288; [2 Same as AutoHideHorzSb(false).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HideHorzSb`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 HideHorzSb][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Unconditionally hides horizontal scrollbar (active if +HeaderCtrl is in absolute mode only).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:MultiSelect`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 MultiSelect][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Enable / disable multiple row selection. ]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 b][2 -|][*2 true][2 `= allow selecting +multiple rows at the same time, ][*2 false][2 `= only one row at +a time]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsMultiSelect`(`)const: [@(0.0.255)2 bool][2 _][*2 IsMultiS +elect][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns true if ArrayCtrl is in multiselect mode.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoBackground`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoBackground][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Sets the widget into transparent mode `- background is +not painted and Transparent is activated `- a result, anything +painted behind the widget is visible, allowing client code to +provide any background it needs.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:PopUpEx`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 PopUpEx][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Activates showing small popup windows with cell content +when mouse is over and cell is to big to fit current dimensions. +Default is activated.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoPopUpEx`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 NoPopUpEx][2 ()]&] +[s0;l288; [2 Same as PopUpEx(false).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoFocusSetCursor`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoFocusSetCursor][2 ()]&] +[s0;l288; [2 Normally, when ArrayCtrl gets a focus and no cursor is +set (and cursor is allowed and there is at least one line), ArrayCtrl +a sets the cursor to the first line. This modifier deactivates +this feature.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:MovingHeader`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 MovingHeader][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 )]&] +[s0;l288; [2 Activates dragging columns in header. Default is active.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoMovingHeader`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoMovingHeader][2 ()]&] +[s0;l288; [2 Same as MovingHeader(false).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnSortFindKey`(bool`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 ColumnSortFindKey][2 (][@(0.0.255)2 bool][2 _][*@3;2 b][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Before ColumnSort orders the ArrayCtrl, the key of current +row (with cursor) is stored and after sorting, it is restored.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AllSorting`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `&][2 _ +][*2 AllSorting][2 ()]&] +[s0;l288; [2 If set, Sorting() is invoked for all columns (added either +before or after this modifier is called).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnSortSecondary`(const ArrayCtrl`:`:Order`&`): [_^ArrayCtrl^2 A +rrayCtrl][@(0.0.255)2 `&][2 _][*2 ColumnSortSecondary][2 (][@(0.0.255)2 const][2 _][_^ArrayCtrl`:`:Order^2 O +rder][@(0.0.255)2 `&][2 _][*@3;2 order][2 )]&] +[s0;l288; [2 Sets secondary sorting predicate for column sorts (see +ColumnSort, Sorting) `- if two cells are equal when performing +sort by column, they are ordered by this predicate.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoColumnSortSecondary`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoColumnSortSecondary][2 ()]&] +[s0;l288; [2 Same as ColumnSortSecondary(false).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnWidths`(const char`*`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 ColumnWidths][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 s][2 )]&] +[s0;l288; [2 Initializes column widths based on a text string containing +blank`-separated decimal numbers, e.g. `"1 4 6 4 1`".]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 s][2 -|control string defining +column widths]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetColumnWidths`(`): [_^String^2 String][2 _][*2 GetColumnW +idths][2 ()]&] +[s0;l288; [2 Returns current column widths in format compatible with +ColumnWidths.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:CursorOverride`(const Image`&`): [_^ArrayCtrl^2 ArrayCt +rl][@(0.0.255)2 `&][2 _][*2 CursorOverride][2 (][@(0.0.255)2 const][2 _][_^Image^2 Image][@(0.0.255)2 `& +][2 _][*@3;2 arrow][2 )]&] +[s0;l288; [2 Overrides mouse cursor to ][*@3;2 arrow][2 . Setting Null +ends override.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:NoCursorOverride`(`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 NoCursorOverride][2 ()]&] +[s0;l288; [2 Same as CursorOverride(Null).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:RowFormat`(const char`*`): [_^String^2 String][2 _][*2 RowF +ormat][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 s][2 )]&] +[s0;l288; [2 Formats a text by substituting ][*2 %s][2 with the array`-specific +term for `'row`' (as set by the ][*2 RowName][2 property). This +is used for array local menu items.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 s][2 -|][*2 Format][2 `-like string +to substitute.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:RowName`(const char`*`): [_^ArrayCtrl^2 ArrayCtrl][@(0.0.255)2 `& +][2 _][*2 RowName][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 s][2 )]&] +[s0;l288; [2 Sets the array`-specific term for `'row`'. This can be +used to customize the local menu terminology according to the +logical content of the array. For instance, when you have an +array with the list of employees, you can call ][*2 RowName(`"employee`")][2 +and the menu items will then read ][/2 `'Insert new employee`', +`'Delete employee`'][2 etc.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 s][2 -|the term to substitute +for `'array row`' in menu items]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;* &] +[s0; [* Column structure programming]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IndexInfo`(int`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 IndexInfo][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 )]&] +[s0;l288; [2 Returns a reference to the ][*2 IdInfo][2 structure describing +a given array index (column in the source data matrix).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the array index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|IdInfo reference +for the given index]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IndexInfo`(const Id`&`): [_^ArrayCtrl`:`:IdInfo^2 IdInf +o][@(0.0.255)2 `&][2 _][*2 IndexInfo][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Returns a reference to the ][*2 IdInfo][2 structure describing +a given array index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|the ][*2 Id][2 index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|IdInfo reference +for the given index]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddIndex`(const Id`&`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo +][@(0.0.255)2 `&][2 _][*2 AddIndex][2 (][@(0.0.255)2 const][2 ][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Adds a new index to the array and assign it a given ][*2 Id][2 +identifier.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|new index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 IdInfo ][2 structure describing the newly added index. The +reference can be used to set additional index properties.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddIndex`(`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 AddIndex][2 ()]&] +[s0;l288; [2 Adds a new index (without an identifier) to the array.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 IdInfo][2 structure describing the newly added index.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetIndexCount`(`)const: [@(0.0.255)2 int][2 _][*2 GetIndexC +ount][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns number of indices in the array.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|index count]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetId`(int`)const: [_^Id^2 Id][2 _][*2 GetId][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 ii][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the identifier of a given index (addresses by +its zero`-based ordinal number).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the queried index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|index identifier +or ][*2 Null][2 if the index has no identifier]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetPos`(const Id`&`)const: [@(0.0.255)2 int][2 _][*2 GetPos +][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the zero`-based positional number of the array +index with a given identifier.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|array index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based index +number, `-1 when not found]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetId`(int`,const Id`&`): [_^ArrayCtrl`:`:IdInfo^2 IdIn +fo][@(0.0.255)2 `&][2 _][*2 SetId][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 , ][@(0.0.255)2 const +][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Sets the identifier for a given array index. This can +be used to set or modify the identifier for a previously added +index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the index to set the identifier for]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|new index identifier (][*2 Null][2 +when none)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 IdInfo][2 descriptive structure for the ][/2 ii][2 `-th index. +The reference can be used to set additional properties of the +altered index.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddKey`(const Id`&`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 AddKey][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Adds a ][/2 primary key][2 index to the table. The ][/2 primary +key][2 is just another name for the first index (index with ordinal +number 0). This is just a handy convention often used for SQL`-based +tables. ][*2 AddKey][2 must be called only once after array initialization +or ][*2 Reset][2 and before calling any other functions adding indices +(like ][*2 AddIndex][2 , ][*2 AddColumn][2 or ][*2 AddCtrl][2 ). When ][*2 GetIndexCount() +> 0 ][2 before the call to this function, this method fails with +an ][*2 ASSERT][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|primary key identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the descriptive ][*2 IdInfo][2 structure for the primary key index.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddKey`(`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 AddKey][2 ()]&] +[s0;l288; [2 Adds a primary key index without an identifier to the +table. This is equivalent to ][*2 AddKey(Null)][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 IdInfo][2 structure describing the primary key index.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetKeyId`(`)const: [_^Id^2 Id][2 _][*2 GetKeyId][2 ()_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns primary key identifier for this table. This is +equivalent to calling ][*2 GetId(0)][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|primary key index +identifier]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddColumn`(const char`*`,int`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddColumn][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 t +ext][2 _`=_NULL, ][@(0.0.255)2 int][2 _][*@3;2 w][2 _`=_][@3;2 0][2 )]&] +[s0;l288; [2 Add a new column`-index pair to the table. The function +adds a (source) index and an (output) column and sets the index +as the data source for the column. This is the most common method +for adding columns to the array.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 text][2 -|column name (displayed +in the array header)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 w][2 -|logical relative column +width]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 Column][2 structure describing the newly added column. +This can be used to set additional properties for the newly added +column and the corresponding header tab.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddColumn`(const Id`&`,const char`*`,int`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddColumn][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 text][2 , ][@(0.0.255)2 int][2 _][*@3;2 w][2 _ +`=_][@3;2 0][2 )]&] +[s0;l288; [2 Adds a new column`-index pair to the table. This is equivalent +to the above two`-parameter version but, in addition, the method +sets the ][*2 Id][2 identifier for the newly created index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|new index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 text][2 -|column name (displayed +in the header)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 w][2 -|logical relative column +width]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 Column][2 structure describing the newly added array column.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddColumnAt`(int`,const char`*`,int`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddColumnAt][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 , +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 text][2 , ][@(0.0.255)2 int][2 _][*@3;2 w][2 _ +`=_][@3;2 0][2 )]&] +[s0;l288; [2 Adds a new column to the table and binds it to a given +source data index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the index to use as source for this column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 text][2 -|column name (displayed +in the header)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 w][2 -|logical relative column +width]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 Column][2 structure describing the newly added array column.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddColumnAt`(const Id`&`,const char`*`,int`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddColumnAt][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , + ][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 text][2 , ][@(0.0.255)2 int][2 _][*@3;2 w +][2 _`=_][@3;2 0][2 )]&] +[s0;l288; [2 Adds a new column to the table and binds it to a given +source data index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +to use as source for the newly added column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 text][2 -|column name (displayed +in the header)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 w][2 -|logical relative column +width]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 Column][2 structure describing the newly added array column.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddRowNumColumn`(const char`*`,int`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddRowNumColumn][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _ +`*][*@3;2 text][2 , ][@(0.0.255)2 int][2 _][*@3;2 w][2 _`=_][@3;2 0][2 )]&] +[s0;l288; [2 Adds a new column to the table. The newly added column +has no source index, it is assumed to have an external data source. +Instead of the source data ][*2 Value][2 object, the current zero`-based +row number is passed to the column`'s ][*2 Convert][2 / ][*2 Display][2 . +This allows the host application to decode somehow the external +data based on the row number. In the current U`+`+ version, the +][/2 RowNum columns][2 cannot be edited (using the standard array +inline editing mechanism).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 text][2 -|column name (displayed +in the header)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 w][2 -|logical relative column +width]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A reference to +the ][*2 Column][2 structure describing the newly added array column.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddCtrl`(Ctrl`&`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 AddCtrl][2 (][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 ctrl][2 )]&] +[s0;l288; [2 Adds a new index`-control pair to the table; the index +keeps the source data and the external control is used to edit +it. The ArrayCtrl handles data transfer between the source data +matrix and the external control. The method returns a reference +the ][*2 IdInfo][2 descriptive structure for the newly added index.]&] +[s0;l288; [*2 Note:][2 it is good to keep in mind that there are a few +differences between the ordinary array cell editors and the freestanding +edit controls. In contrast with the cell editors, which appear +only when the row is opened for editing, the freestanding controls +are present all the time. For instance, the ArrayCtrl automatically +disables the controls when the cursor moves away from the table +(using ][*2 KillCursor][2 ) and re`-enables them after it comes back. +This is important e.g. if you want to implement an additional +logic enabling some of the controls only depending on the circumstances; +in such case, you have to use one of the notification callbacks +(like ][*2 WhenEnterRow][2 ) to force your additional behaviour +on the controls.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ctrl][2 -|control to attach to +the given index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the IdInfo structure describing the newly added index]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddCtrl`(const Id`&`,Ctrl`&`): [_^ArrayCtrl`:`:IdInfo^2 I +dInfo][@(0.0.255)2 `&][2 _][*2 AddCtrl][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , +][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 ctrl][2 )]&] +[s0;l288; [2 Adds a new index`-control pair to the table. This is identical +to the above version with the only difference that the newly +added index is assigned an ][*2 Id][2 identifier at the same time.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|the identifier to assign +to the newly created index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ctrl][2 -|freestanding control +used to edit the given index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the IdInfo structure describing the newly added index]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddCtrlAt`(int`,Ctrl`&`): [@(0.0.255)2 void][2 _][*2 AddCtr +lAt][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 , ][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 ctrl][2 )]&] +[s0;l288; [2 Adds a new control to the table and binds it to the index +with given ordinal number. You can use this method to create +the binding between the control and an arbitrary source index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the index to bind to this control]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ctrl][2 -|freestanding control +used to edit the ][/2 ii][2 `-th data index]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddCtrlAt`(const Id`&`,Ctrl`&`): [@(0.0.255)2 void][2 _][*2 A +ddCtrlAt][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , ][_^Ctrl^2 Ctrl][@(0.0.255)2 `& +][2 _][*@3;2 ctrl][2 )]&] +[s0;l288; [2 Adds a new control to the table and binds it to the index +with given identifier.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +to bind to this control]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ctrl][2 -|freestanding control +used to edit the index with identifier ][/2 id]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AddRowNumCtrl`(Ctrl`&`): [@(0.0.255)2 void][2 _][*2 AddRowN +umCtrl][2 (][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 ctrl][2 )]&] +[s0;l288; [2 Adds a new freestanding control to the table. The control +is not bound to any source data index. During cursor movement +in the array, array uses the control`'s ][*2 SetData][2 method to +set it to the current row number. The control must be ready for +that and it can use the row number value to decode some externally +located data for display. In the current U`+`+ version, such +controls cannot be used for editing (there is currently no clean +way to store the edited data back to its external storage).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ctrl][2 -|][/2 RowNum][2 `-based freestanding +editor control]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetColumnCount`(`)const: [@(0.0.255)2 int][2 _][*2 GetColum +nCount][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the current number of (output) columns in the +array.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|number of columns]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:FindColumnWithPos`(int`)const: [@(0.0.255)2 int][2 _][*2 Fi +ndColumnWithPos][2 (][@(0.0.255)2 int][2 _][*@3;2 pos][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the zero`-based index of a column based on its +source data index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 pos][2 -|ordinal number of the +source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|ordinal number +of the column having the given index as its source, `-1 when +not found]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:FindColumnWithId`(const Id`&`)const: [@(0.0.255)2 int][2 _ +][*2 FindColumnWithId][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 con +st]&] +[s0;l288; [2 Returns the zero`-based index of a column based on its +source data index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|ordinal number +of the column having the given index as its source, `-1 when +not found]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnAt`(int`): [_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `& +][2 _][*2 ColumnAt][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Returns the ][*2 Column][2 structure describing a given column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the ][*2 Column][2 structure describing the given column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnAt`(const Id`&`): [_^ArrayCtrl`:`:Column^2 Column +][@(0.0.255)2 `&][2 _][*2 ColumnAt][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Returns the ][*2 Column][2 structure describing a given column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a constant reference +to the ][*2 Column][2 structure describing the given column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnAt`(int`)const: [@(0.0.255)2 const][2 _][_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 ColumnAt][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 cons +t]&] +[s0;l288; [2 Returns the ][*2 Column][2 structure describing a column +with given source index. This is merely the const version of +the above method; it can be used to query properties for the +column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +used as source for the column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the ][*2 Column][2 structure describing the given column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnAt`(const Id`&`)const: [@(0.0.255)2 const][2 _][_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 ColumnAt][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns a constant reference to the ][*2 Column][2 structure +describing a column with given source index. This is the constant +version of the above method; it can be used to query properties +for the column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +used as source for the column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a constant reference +to the ][*2 Column][2 structure describing the given column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderTab`(int`): [_^HeaderCtrl`:`:Column^2 HeaderCtrl`: +:Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Returns the ][*^topic`:`/`/CtrlLib`/src`/HeaderCtrl`$en`-us`#`:`:HeaderCtrl`:`:Column`:`:Min`(int`)^2 H +eaderCtrl`::Column][2 descriptive structure for the given column. +The correspondence between the array columns and the header tabs +is 1:1, so that the indices of both are always the same (][*2 array.GetColumnCount() + `=`= array.HeaderObject().GetCount()][2 holds all the time).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the ][*2 HeaderCtrl`::Column][2 structure. This can be used to set +additional properties of the header column (e.g. column width +constraints, font and icon for the column title etc.)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderTab`(int`)const: [@(0.0.255)2 const][2 _][_^HeaderCtrl`:`:Column^2 H +eaderCtrl`::Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns a constant reference to the ][*2 HeaderCtrl`::Column][2 +structure for the given column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the ][*2 HeaderCtrl`::Column][2 structure. This can be used to set +additional properties of the header column (e.g. column width +constraints, font and icon for the column title etc.)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderTab`(const Id`&`): [_^HeaderCtrl`:`:Column^2 Head +erCtrl`::Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 (][@(0.0.255)2 const +][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Returns the ][*2 HeaderCtrl`::Column][2 descriptive structure +for the column bound to a given source index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +used as source for the column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the ][*2 HeaderCtrl`::Column][2 structure]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderTab`(const Id`&`)const: [@(0.0.255)2 const][2 _][_^HeaderCtrl`:`:Column^2 H +eaderCtrl`::Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 (][@(0.0.255)2 const +][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns a constant reference to the ][*2 HeaderCtrl`::Column][2 +descriptive structure for the column bound to a given source +index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the index +used as source for the column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a constant reference +to the ][*2 HeaderCtrl`::Column][2 structure]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderObject`(`)const: [@(0.0.255)2 const][2 _][_^HeaderCtrl^2 H +eaderCtrl][@(0.0.255)2 `&][2 _][*2 HeaderObject][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns a non`-constant reference to the ][*2 HeaderCtrl][2 +object for this table. The reference can be further used to alter +properties of the table header (tab visibility, header visual +mode and so on).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A non`-constant +reference to the table HeaderCtrl object.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:HeaderObject`(`): [_^HeaderCtrl^2 HeaderCtrl][@(0.0.255)2 `& +][2 _][*2 HeaderObject][2 ()]&] +[s0;l288; [2 This is just the constant version of the above method; +when called on a constant ][*2 ArrayCtrl][2 reference, it returns +a constant reference to its underlying HeaderCtrl object which +can be then used to query additional header information.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|A constant reference +to the table HeaderCtrl object.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SerializeHeader`(Stream`&`): [@(0.0.255)2 void][2 _][*2 Ser +ializeHeader][2 (][_^Stream^2 Stream][@(0.0.255)2 `&][2 _][*@3;2 s][2 )]&] +[s0;l288; [2 Serializes all information pertaining to the array header +(mainly the user`-set column widths). This is equivalent to calling +][*2 HeaderObject().Serialize(s)][2 . The main purpose of this function +is to allow storing header configuration to be restored upon +opening the dialog or the application for the next time. This +function is now deprecated in favor of SerializeSettings.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 s][2 -|the ][*^topic`:`/`/Core`/src`/Stream`$en`-us^2 S +tream][2 object to serialize the header to/from]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SerializeSettings`(Stream`&`): [@(0.0.255)2 void][2 _][*2 S +erializeSettings][2 (][_^Stream^2 Stream][@(0.0.255)2 `&][2 _][*@3;2 s][2 )]&] +[s0;l288; [2 Serializes all information pertaining to the array header +(mainly the user`-set column widths) and the setting of sort +column. The main purpose of this function is to allow storing +configuration to be restored upon opening the dialog or the application +for the next time.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetDisplay`(int`,int`,const Display`&`): [@(0.0.255)2 v +oid][2 _][*2 SetDisplay][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 col][2 , + ][@(0.0.255)2 const][2 _][_^Display^2 Display][@(0.0.255)2 `&][2 _][*@3;2 d][2 )]&] +[s0;l288; [2 Sets the ][*2 Display][2 object for a given array cell.]&] +[s0;l288;*2 &] +[s0;l288; [*2 Note:][2 the ownership to the Display object is not transferred +by this call. The ArrayCtrl stores a mere pointer to it and it +is the responsibility of the programmer to keep the Display object +alive as long as necessary (until the array is shut down or the +cell display changed via another call to SetDisplay). In fact, +most Display`-based objects don`'t support data copying at all. +In any case, copying Displays is not a very good practice and +is very prone to slicing (as most actual Displays are actually +derived classes with additional data members).]&] +[s0;l288;2 &] +[s0;l288; [2 In many cases it would be relatively safe to assume that +the Display is not used unless the array is actually painted +(e.g., when the control is not bound to a parent or when its +view has zero size), but it is not a very wise practice and it +can fail in very weird ways under special circumstances (like +making screenshots or graphical exports from the array control).]&] +[s0;l288;2 &] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 j][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 d][2 -|display to use]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetDisplay`(int`,int`): [@(0.0.255)2 const][2 _][_^Display^2 D +isplay][@(0.0.255)2 `&][2 _][*2 GetDisplay][2 (][@(0.0.255)2 int][2 _][*@3;2 row][2 , +][@(0.0.255)2 int][2 _][*@3;2 col][2 )]&] +[s0;l288; [2 Returns a reference to the Display object for the given +array cell.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 row][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 col][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|a reference to +the Display object.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetDisplay`(int`): [@(0.0.255)2 const][2 _][_^Display^2 Dis +play][@(0.0.255)2 `&][2 _][*2 GetDisplay][2 (][@(0.0.255)2 int][2 _][*@3;2 col][2 )]&] +[s0;l288; [2 Returns a reference to the Display object for the given +array column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 col][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|constant reference +to the column Display]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetCtrl`(int`,int`,Ctrl`&`,bool`): [@(0.0.255)2 void][2 _ +][*2 SetCtrl][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 col][2 , +][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 ctrl][2 , ][@(0.0.255)2 bool][2 _][*@3;2 value][2 _`=_][@(0.0.255)2 t +rue][2 )]&] +[s0;l288; [2 Sets an external control to use as the editor for a single +array cell. Naturally, the same Ctrl object cannot be used as +the editor for multiple array cells. If the position of Ctrl +is equivalent to `'SetRect(0, 0, 0, 0)`', which is the default +value, Ctrl is resized to fit the ArrayCtrl cell accurately, +otherwise the position represents the position within the cell. +If ][*@3;2 value][2 is true, then the Ctrl represents the value +of the cell, otherwise it is independent of it.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetTotalCy`(`)const: [@(0.0.255)2 int][2 _][*2 GetTotalCy][2 ( +)_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns total height of the array (sum of the individual +line heights for all array rows)]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|array height in +pixels]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetLineAt`(int`)const: [@(0.0.255)2 int][2 _][*2 GetLineAt][2 ( +][@(0.0.255)2 int][2 _][*@3;2 y][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Locates the array row according to given ][/2 y][2 coordinate +(such array row ][/2 r][2 for which ][*2 GetLineY(r) <`= y `&`& GetLineY(r) +`+ GetLineCy(r) > y][2 ).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 y][2 -|vertical pixel coordinate +to locate]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based row +number or `-1 when not found]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetClickColumn`(`)const: [@(0.0.255)2 int][2 _][*2 GetClick +Column][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns column index of the last clicked column in the +array. If the click happens past the last row of array, returns +Null.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based index +of the relevant column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetClickRow`(`)const: [@(0.0.255)2 int][2 _][*2 GetClickRow +][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns column index of the last clicked row in the array. +If the click happens past the last row of array, returns Null.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based index +of the relevant column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetClickPos`(`)const: [_^Point^2 Point][2 _][*2 GetClickPos +][2 ()_][@(0.0.255)2 const]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 Point(GetClickColumn(), +GetClickRow())][2 .]&] +[s0;0 &] +[s0;* &] +[s0; [* Data setting and retrieval]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetCount`(int`): [@(0.0.255)2 void][2 _][*2 SetCount][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 c][2 )]&] +[s0;l288; [2 Sets the number of rows in the array. This extends or +trims the source matrix as necessary. When using the Ctrl`-based +individual cell editors, as a side`-effect of this call some +controls can be constructed or destroyed.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 c][2 -|new row count]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetVirtualCount`(int`): [@(0.0.255)2 void][2 _][*2 SetVirtu +alCount][2 (][@(0.0.255)2 int][2 _][*@3;2 c][2 )]&] +[s0;l288; [2 Sets the number of rows in an array with external data. +This makes sense only when all the ][/2 Column`'s][2 and ][/2 Ctrl`'s][2 +of the array are ][/2 rownum][2 `-based. The function doesn`'t physically +allocate any source data matrix space, it just makes the array +`'think`' it has ][/2 c][2 rows (this is of course necessary for +the Paint routine, for cursor / selection management and so on).]&] +[s0;l288; [*2 Note:][2 in the current implementation, selection flags +for the individual rows are kept in the row objects. Therefore +it is not very wise to use multiselection for arrays with external +data, because as soon as the last row is selected, all row storage +structures are allocated as a side effect to keep the selection +flags.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 c][2 -|new `'virtual`' number +of rows]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetCount`(`)const: [@(0.0.255)2 int][2 _][*2 GetCount][2 ()_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns the number of rows in the array. In fact, this +returns the maximum of the number of `'real`' source matrix rows +(as set by the SetCount / Add / Insert methods) and the `'virtual`' +row count (as se by SetVirtualCount). By checking the implementation +of this method, you can easily find that, simply,]&] +[s0;l288;2 &] +[s0;l288; [C2 int ArrayCtrl`::GetCount() const `{]&] +[s0;l288; [C2 -|-|return max(virtualcount, array.GetCount());]&] +[s0;l288; [C2 `}]&] +[s0;l288;2 &] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|Number of rows +in the array.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Clear`(`): [@(0.0.255)2 void][2 _][*2 Clear][2 ()]&] +[s0;l288; [2 Clears the array source data matrix and sets the virtual +row count to 0.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Shrink`(`): [@(0.0.255)2 void][2 _][*2 Shrink][2 ()]&] +[s0;l288; [2 Shrinks the source data array, i.e. reallocates the data +to the minimum required memory space.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Get`(int`,int`)const: [_^Value^2 Value][2 _][*2 Get][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 ii][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the value at a given location in the source data +matrix.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based index ordinal +number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the given +location in the source data matrix]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Get`(int`,const Id`&`)const: [_^Value^2 Value][2 _][*2 Get][2 ( +][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns the value at a given location in the source data +matrix. In this version, the source indices are addressed by +their identifiers.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the given +location in the source data matrix]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Get`(int`)const: [_^Value^2 Value][2 _][*2 Get][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 ii][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the value of a given source index at the currently +active cursor row. This is equivalent to ][*2 Get(GetCursor(), +ii)][2 . When the row is currently being edited, the function returns +the `'new`' value (the current value of the respective editor +control, i.e. potentially edited).]&] +[s0;l288; [*2 Note:][2 when the cursor row is not set (when ][*2 !IsCursor()][2 ), +the function fails with an ][*2 ASSERT][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based index ordinal +number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at a given +location in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Get`(const Id`&`)const: [_^Value^2 Value][2 _][*2 Get][2 (][@(0.0.255)2 c +onst ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the value of a given source index at the currently +active cursor row. This is equivalent to ][*2 Get(GetCursor(), +id)][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the given +location in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetOriginal`(int`)const: [_^Value^2 Value][2 _][*2 GetOrigi +nal][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the `'original`' value of a given source index +at the currently active cursor row. When the row is open for +editing, this function returns the `'old`' value before any editing +took place.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based index ordinal +number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the given +location in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetOriginal`(const Id`&`)const: [_^Value^2 Value][2 _][*2 G +etOriginal][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the `'original`' value (i.e., without any editing +changed applied) of a given source index at the currently active +cursor row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the given +location in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetKey`(`)const: [_^Value^2 Value][2 _][*2 GetKey][2 ()_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns the value of the current row`'s primary key. This +is equivalent to ][*2 Get(0)][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the index +#0 in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetOriginalKey`(`)const: [_^Value^2 Value][2 _][*2 GetOrigi +nalKey][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the original value of the current row`'s primary +key. During editing, the function returns the value at the time +of opening the row for editing, i.e. without any editing changes +applied. This is equivalent to ][*2 GetOriginal(0)][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value at the index +#0 in the cursor row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,int`,const Value`&`): [@(0.0.255)2 void][2 _][*2 S +et][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 ii][2 , +][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v][2 )]&] +[s0;l288; [2 Sets the value at a given location in the source data +matrix.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based index ordinal +number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|value to set to the given +cell]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,const Id`&`,const Value`&`): [@(0.0.255)2 voi +d][2 _][*2 Set][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 i +d][2 , ][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v][2 )]&] +[s0;l288; [2 Sets the value at a given location in the source data +matrix. ]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|value to set to the given +cell]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,const Value`&`): [@(0.0.255)2 void][2 _][*2 Set][2 ( +][@(0.0.255)2 int][2 _][*@3;2 ii][2 , ][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _ +][*@3;2 v][2 )]&] +[s0;l288; [2 Modifies the value at a given location in the cursor row. +When the row is open for editing, the function immediately changes +the value in the appropriate editor control.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based index ordinal +number]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|value to set]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(const Id`&`,const Value`&`): [@(0.0.255)2 void][2 _][*2 S +et][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , ][@(0.0.255)2 const][2 _][_^Value^2 Va +lue][@(0.0.255)2 `&][2 _][*@3;2 v][2 )]&] +[s0;l288; [2 Modifies the value at a given location in the cursor row. +This overloaded version uses the ][*2 Id][2 identifier to address +the relevant index.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|value to set]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetColumn`(int`,int`)const: [_^Value^2 Value][2 _][*2 GetCo +lumn][2 (][@(0.0.255)2 int][2 _][*@3;2 row][2 , ][@(0.0.255)2 int][2 _][*@3;2 col][2 )_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Returns the value of a given column. This depends on the +column`-index mapping established when adding columns to the +table. When the column is a ][/2 rownum][2 type (it is bound to +no source indices), the function just returns the ][/2 row][2 parameter. +For columns with a single source index, the function returns +the value of the mapped source index. For columns with multiple +source indices, the function returns a ][*2 ValueArray ][2 containing +the values of its source indices.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 row][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 col][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|value of the given +column]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetConvertedColumn`(int`,int`): [_^Value^2 Value][2 _][*2 G +etConvertedColumn][2 (][@(0.0.255)2 int][2 _][*@3;2 row][2 , ][@(0.0.255)2 int][2 _][*@3;2 col][2 ) +]&] +[s0;l288; [2 Returns the value of a given column after application +of its ][*2 Convert][2 . For performance reasons, the values obtained +by calls to the ][*2 Convert`::Format][2 methods are cached internally +within the ArrayCtrl object. You can manipulate the conversion +cache using the methods ][*^topic`:`/`/CtrlLib`/src`/ArrayCtrl`$en`-us`#`:`:ArrayCtrl`:`:ClearCache`(`)^2 C +learCache][2 and][*2 ][*^topic`:`/`/CtrlLib`/src`/ArrayCtrl`$en`-us`#`:`:ArrayCtrl`:`:InvalidateCache`(int`)^2 I +nvalidateCache][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 row][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 col][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|the converted cell +value]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ReadRow`(int`)const: [_^Vector^2 Vector][2 <][_^Value^2 Val +ue][2 >_][*2 ReadRow][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns a ][*2 Vector][2 containing the values of all source +indices in the given row. Invariantly, the ][*2 GetCount()][2 of +the returned array is equal to the ][*2 GetIndexCount()][2 of the +source ArrayCtrl.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|an array of all +source values in the given row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,const Vector``&`): [@(0.0.255)2 void][2 _ +][*2 Set][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const][2 _][_^Vector^2 Vector][2 <][_^Value^2 V +alue][2 >`&_][*@3;2 v][2 )]&] +[s0;l288; [2 Modified a given row by setting all source index values +to values passed in the parameter ][/2 v][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|an array of values to set +to the source data matrix row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(`): [@(0.0.255)2 void][2 _][*2 Add][2 ()]&] +[s0;l288; [2 Adds an empty row to the source data matrix.]&] +[s0;l288; [*2 Note:][2 the ][*2 InsertValue][2 property of the ][*2 IdInfo][2 +structure defines a method to generate / retrieve default values +for newly inserted rows. However, these values are only used +during the GUI`-based ][*2 DoInsert][2 method and do not apply to +the ][*2 Add][2 method. If you need to set the newly added source +matrix row to some non`-null defaults, you have to modify the +relevant cells manually.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(const Vector``&`): [@(0.0.255)2 void][2 _][*2 A +dd][2 (][@(0.0.255)2 const][2 _][_^Vector^2 Vector][2 <][_^Value^2 Value][2 >`&_][*@3;2 v][2 )]&] +[s0;l288; [2 Adds a new row at the end of the source data matrix. The +][*^topic`:`/`/Core`/src`/Vector`$en`-us^2 Vector][2 parameter contains +the values to be used to initialize the new row of the matrix.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|new matrix row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,const VectorMap``&`): [@(0.0.255)2 v +oid][2 _][*2 Set][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const][2 _][_^VectorMap^2 Vec +torMap][2 <][_^String^2 String][2 , ][_^Value^2 Value][2 >`&_][*@3;2 m][2 )]&] +[s0;l288; [2 Sets the row based on map. Keys are matched to row Ids, +keys that are not found are ignored, those found are assigned +correspoding map values.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Set`(int`,const ValueMap`&`): [@(0.0.255)2 void][2 _][*2 Se +t][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const][2 _][_^ValueMap^2 ValueMap][@(0.0.255)2 `& +][2 _][*@3;2 m][2 )]&] +[s0;l288; [2 Sets the row based on map. Keys are matched to row Ids, +keys that are not found are ignored, those found are assigned +correspoding map values.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(const VectorMap``&`): [@(0.0.255)2 v +oid][2 _][*2 Add][2 (][@(0.0.255)2 const][2 _][_^VectorMap^2 VectorMap][2 <][_^String^2 String][2 , + ][_^Value^2 Value][2 >`&_][*@3;2 m][2 )]&] +[s0;l288; [2 Adds the row based on map. Keys are matched to row Ids, +keys that are not found are ignored, those found are assigned +correspoding map values.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(const ValueMap`&`): [@(0.0.255)2 void][2 _][*2 Add][2 (][@(0.0.255)2 c +onst][2 _][_^ValueMap^2 ValueMap][@(0.0.255)2 `&][2 _][*@3;2 m][2 )]&] +[s0;l288; [2 Adds the row based on map. Keys are matched to row Ids, +keys that are not found are ignored, those found are assigned +correspoding map values.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(const Value`&`[`,const Value`&`]`.`.`.`): [@(0.0.255)2 v +oid][2 _][*2 Add][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _`[, +][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _`]...)]&] +[s0;l288; [2 Adds a new row at the bottom of the source data matrix. +This is in fact a series of functions (generated automatically +using the ][*2 Expand][2 macro) which takes an arbitrary number +of arguments. Its arguments are used to initialize the source +indices in the newly added row.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Add`(const Nuller`&`): [@(0.0.255)2 void][2 _][*2 Add][2 (][@(0.0.255)2 c +onst][2 _][_^Nuller^2 Nuller][@(0.0.255)2 `&][2 _][*@3;2 null][2 )]&] +[s0;l288; [2 This is helper method required for correct overloading +resolution of Add(Null).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Insert`(int`): [@(0.0.255)2 void][2 _][*2 Insert][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Inserts a new row into the source array. All indices are +initialized to ][*2 Null][2 values. The ][*2 InsertValue][2 property +doesn`'t apply; if you need to set the newly created row to some +non`-trivial values, you have to do so manually.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based position of +the newly created row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Insert`(int`,const Vector``&`): [@(0.0.255)2 vo +id][2 _][*2 Insert][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 const][2 _][_^Vector^2 Vect +or][2 <][_^Value^2 Value][2 >`&_][*@3;2 v][2 )]&] +[s0;l288; [2 Inserts a new row into the array at a given position. +The second parameter, ][/2 v][2 , is used to initialize the source +indices of the newly created row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|a vector of values used +to initialize the source indices of the given row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Remove`(int`): [@(0.0.255)2 void][2 _][*2 Remove][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Removes the given source data row.]&] +[s0;l288; [*2 Note:][2 the ][*2 AskRemove][2 property of the ][*2 ArrayCtrl][2 +object tells whether a confirmation dialog should pop up every +time the user wants to remove a row. However, this method applies +only to the GUI`-based row removal; the ][*2 Remove][2 method always +removes the requested row unconditionally without popping up +any confirmation dialog.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based index of the +row to remove]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SwapUp`(`): [@(0.0.255)2 void][2 _][*2 SwapUp][2 ()]&] +[s0;l288; [2 Exchanges the cursor row with the preceding row, effectively +moving it up.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SwapDown`(`): [@(0.0.255)2 void][2 _][*2 SwapDown][2 ()]&] +[s0;l288; [2 Exchanges the cursor row with following row, effectively +moving it down.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(const ArrayCtrl`:`:Order`&`): [@(0.0.255)2 void][2 _ +][*2 Sort][2 (][@(0.0.255)2 const][2 _][_^ArrayCtrl`:`:Order^2 ArrayCtrl`::Order][@(0.0.255)2 `& +][2 _][*@3;2 order][2 )]&] +[s0;l288; [2 Sorts the array rows according to a given ordering predicate. +The ][*2 ArrayCtrl`::Order][2 object defines the ordering predicate; +its ][*2 operator ()][2 should return ][*2 true][2 whenever its first +parameter (a vector containing the values of all source indices +in a row) is less than its second parameter.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 order][2 -|]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(int`,int`,const ArrayCtrl`:`:Order`&`): [@(0.0.255)2 v +oid][2 _][*2 Sort][2 (][@(0.0.255)2 int][2 _][*@3;2 from][2 , ][@(0.0.255)2 int][2 _][*@3;2 count][2 , +][@(0.0.255)2 const][2 _][_^ArrayCtrl`:`:Order^2 ArrayCtrl`::Order][@(0.0.255)2 `&][2 _][*@3;2 o +rder][2 )]&] +[s0;l288; [2 Sorts a portion of the array using a given ordering predicate.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 from][2 -|zero`-based index of +the first row to sort]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 count][2 -|number of rows to be +sorted]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 order][2 -|the ordering predicate +object. The object should be derived from ][*2 ArrayCtrl`::Order][2 +and should override the ][*2 operator ()][2 method. This method +should return ][*2 true ][2 whenever its first parameter (a vector +containing all source index values for a certain row) is less +than its second parameter.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(int`(`*`)`(const Vector``&v1`,const Vector``&v2`)`): [@(0.0.255)2 v +oid][2 _][*2 Sort][2 (][@(0.0.255)2 int][2 _(`*][*@3;2 compare][2 )(][@(0.0.255)2 const][2 _Vector< +Value>`&_v1, ][@(0.0.255)2 const][2 _Vector`&_v2))]&] +[s0;l288; [2 Sorts the array rows according to the order defined by +the specified ordering predicate ][/2 compare][2 . This is supposed +to be a global function returning ][*2 true][2 whenever its first +parameter (][/2 v1][2 , an array consisting of all source indices +within a row) is less than the second parameter ][/2 v2][2 (according +to the desired ordering).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 compare][2 -|the ordering predicate; +_the function is supposed to return ][*2 true][2 whenever its first +parameter (][/2 v1][2 ) is less than the second parameter (][/2 v2][2 ) +according to the desired ordering.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(int`,int`(`*`)`(const Value`&v1`,const Value`&v2`)`): [@(0.0.255)2 v +oid][2 _][*2 Sort][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 , ][@(0.0.255)2 int][2 _(`*][*@3;2 compare][2 ) +(][@(0.0.255)2 const][2 _Value][@(0.0.255)2 `&][2 _v1, ][@(0.0.255)2 const][2 _Value][@(0.0.255)2 `& +][2 _v2)_`=_StdValueCompare)]&] +[s0;l288; [2 Sorts the array rows according to the given ordering predicate +for the source index with a given ordinal number. When not explicitly +specified, the ][*2 StdValueCompare][2 function is used as the default +comparison predicate.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the source index used for sorting]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 compare][2 -|the sorting predicate +function: the function is supposed to return ][*2 true][2 whenever +its first parameter (][/2 v1][2 ) is less than the second parameter +(][/2 v2][2 ) according to the desired ordering.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(const Id`&`,int`(`*`)`(const Value`&v1`,const Value`&v2`)`): [@(0.0.255)2 v +oid][2 _][*2 Sort][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , ][@(0.0.255)2 int][2 _(`* +][*@3;2 compare][2 )(][@(0.0.255)2 const][2 _Value][@(0.0.255)2 `&][2 _v1, +][@(0.0.255)2 const][2 _Value][@(0.0.255)2 `&][2 _v2)_`=_StdValueCompare)]&] +[s0;l288; [2 Sorts the array rows according to the given ordering predicate +for the source index with a given identifier. When not explicitly +specified, the ][*2 StdValueCompare][2 function is used as the default +comparison predicate.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|identifier of the source +index used for sorting]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 compare][2 -|the sorting predicate +function: the function is supposed to return ][*2 true][2 whenever +its first parameter (][/2 v1][2 ) is less than the second parameter +(][/2 v2][2 ) according to the desired ordering .]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Sort`(`): [@(0.0.255)2 void][2 _][*2 Sort][2 ()]&] +[s0;l288; [2 Sorts the array according to the default ordering predicate +for the first source index. This is equivalent to calling ][*2 Sort(0)][2 .]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ColumnSort`(int`,const ValueOrder`&`): [@(0.0.255)2 voi +d][2 _][*2 ColumnSort][2 (][@(0.0.255)2 int][2 _][*@3;2 column][2 , ][@(0.0.255)2 const][2 _][_^ValueOrder^2 V +alueOrder][@(0.0.255)2 `&][2 _][*@3;2 order][2 )]&] +[s0;l288; [2 Sorts by the column. Note that this is different from +Sort, because the final converted value of column is used (which +can even be combination of more indexes).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetSortColumn`(int`,bool`): [@(0.0.255)2 void][2 _][*2 SetS +ortColumn][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 , ][@(0.0.255)2 bool][2 _][*@3;2 descending][2 _`= +_][@(0.0.255)2 false][2 )]&] +[s0;l288; [2 Sets the `"sorting`" column and calls DoColumnSort. This +setting is used by DoColumnSort.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ToggleSortColumn`(int`): [@(0.0.255)2 void][2 _][*2 ToggleS +ortColumn][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 )]&] +[s0;l288; [2 Similar to SetSortColumn, but if the column is already +set, descending flag is inverted; otherwise descending flag is +set to false (indicating ascending sort).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoColumnSort`(`): [@(0.0.255)2 void][2 _][*2 DoColumnSort][2 ( +)]&] +[s0;l288; [2 Sorts the array by sorting column and indicates it by +setting an image in the header.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ClearCache`(`): [@(0.0.255)2 void][2 _][*2 ClearCache][2 ()]&] +[s0;l288; [2 Invalidates the whole ][/2 convert cache][2 . The convert +cache keeps the results of the ][*2 Convert`::Format][2 method applied +to individual array data cells for performance reasons. Whenever +you call the ][*2 ClearCache][2 method, all cache entries are marked +as obsolete and the ][*2 Convert][2 `'s ][*2 Format][2 method will be +called as soon as the converted value of a table cell is required +(usually during the next ][*2 Paint][2 ).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:InvalidateCache`(int`): [@(0.0.255)2 void][2 _][*2 Invalida +teCache][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Invalidates a given row in the ][/2 convert cache][2 . For +performance reasons, the results of the ][*2 Convert`::Format][2 +method applied to the individual data cells are kept in a cache. +This function marks a given row of the cache as obsolete; this +means the next time the converted values are to be used (usually +within the ][*2 Paint][2 routine or when setting up the row editor +controls), the ][*2 Convert][2 objects are used again to generate +the actualized output values.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;0 &] +[s0; &] +[s0; [* Cursor and selection management]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollUp`(`): [@(0.0.255)2 void][2 _][*2 ScrollUp][2 ()]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollDown`(`): [@(0.0.255)2 void][2 _][*2 ScrollDown][2 ()]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollPageUp`(`): [@(0.0.255)2 void][2 _][*2 ScrollPageUp][2 ( +)]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollPageDown`(`): [@(0.0.255)2 void][2 _][*2 ScrollPageDo +wn][2 ()]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollEnd`(`): [@(0.0.255)2 void][2 _][*2 ScrollEnd][2 ()]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollBegin`(`): [@(0.0.255)2 void][2 _][*2 ScrollBegin][2 () +]&] +[s0;l288; [2 Scrolls the content of ArrayCtrl.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetSelectCount`(`)const: [@(0.0.255)2 int][2 _][*2 GetSelec +tCount][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the number of selected row within the table.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|number of selected +records (in the range ][/2 `[0 .. GetCount()`]][2 )]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsSelection`(`)const: [@(0.0.255)2 bool][2 _][*2 IsSelectio +n][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Checks whether any rows are selected. Equivalent to ][*2 GetSelectCount() +> 0][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= there +is at least one selected row, ][*2 false][2 `= there is none.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Select`(int`,bool`): [@(0.0.255)2 void][2 _][*2 Select][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 , ][@(0.0.255)2 bool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Selects / unselects a given row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 sel][2 -|][*2 true][2 `= add row +to the current selection, ][*2 false][2 `= remove row from selection]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Select`(int`,int`,bool`): [@(0.0.255)2 void][2 _][*2 Select +][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 , ][@(0.0.255)2 int][2 _][*@3;2 count][2 , +][@(0.0.255)2 bool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Selects / unselects a given row range.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based index of the +first row to select / unselect]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 count][2 -|number of rows to select +/ unselect]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 sel][2 -|][*2 true][2 `= select the +rows, ][*2 false][2 `= unselect the rows]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsSelected`(int`)const: [@(0.0.255)2 bool][2 _][*2 IsSelect +ed][2 (][@(0.0.255)2 int][2 _][*@3;2 i][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Checks whether a given row is selected. For tables without +the multiselection option, this is equal to the check ][*2 GetCursor() +`=`= i][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index to +check for selection]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row +is selected, ][*2 false][2 `= not selected]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsSel`(int`)const: [@(0.0.255)2 bool][2 _][*2 IsSel][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 If there is selection in the widget, returns true if ][*@3;2 i][2 +is selected, otherwise returns true if cursor is at ][*@3;2 i][2 .]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ClearSelection`(`): [@(0.0.255)2 void][2 _][*2 ClearSelecti +on][2 ()]&] +[s0;l288; [2 Clears the current selection (unselects all selected rows).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsCursor`(`)const: [@(0.0.255)2 bool][2 _][*2 IsCursor][2 ()_ +][@(0.0.255)2 const]&] +[s0;l288; [2 Checks whether the cursor is within the table. This is +equivalent to ][*2 GetCursor()_>`=_0][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetCursor`(int`): [@(0.0.255)2 bool][2 _][*2 SetCursor][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 i][2 )]&] +[s0;l288; [2 Sets the current cursor row. When an array row is open +for editing, the function first commits the edited row, then +moved the cursor to the new row. When the edited row cannot be +commited, the function returns ][*2 false][2 and doesn`'t change +the cursor location.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 i][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= cursor +has been moved, ][*2 false ][2 when not (when committing the previously +edited row failed)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:KillCursor`(`): [@(0.0.255)2 bool][2 _][*2 KillCursor][2 ()]&] +[s0;l288; [2 Moves the cursor away from the array. When an array row +is open for editing, the function first commits the edited row, +then moved the cursor away from the array. When the edited row +cannot be commited, the function returns ][*2 false][2 and doesn`'t +change the cursor location.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= cursor +has been moved away from the array, ][*2 false][2 when not (when +committing the previously edited row failed)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:CancelCursor`(`): [@(0.0.255)2 void][2 _][*2 CancelCursor][2 ( +)]&] +[s0;l288; [2 Cancels editing of the row being currently edited. All +changes made in the individual column editors are rejected.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetCursor`(`)const: [@(0.0.255)2 int][2 _][*2 GetCursor][2 () +_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the current cursor row, `-1 when none.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based cursor +row index, `-1 `= cursor is not in the array]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GoBegin`(`): [@(0.0.255)2 void][2 _][*2 GoBegin][2 ()]&] +[s0;l288; [2 Moves the cursor to the first row in the array (equivalent +to ][*2 SetCursor(0)][2 ).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GoEnd`(`): [@(0.0.255)2 void][2 _][*2 GoEnd][2 ()]&] +[s0;l288; [2 Moves the cursor to the last array row (equivalent to +][*2 SetCursor(GetCount() `- 1)][2 ).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetCursorSc`(`)const: [@(0.0.255)2 int][2 _][*2 GetCursorSc +][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the visual vertical position of the cursor row +relative to the current view. This method, in combination with +][*2 ScCursor][2 , can be used to reposition the cursor row while +maintaining the same visual position of the row within the array +view.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|an integer describing +the vertical position of the cursor row relative to the array +view]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScCursor`(int`): [@(0.0.255)2 void][2 _][*2 ScCursor][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 a][2 )]&] +[s0;l288; [2 Modifies the scrollbar position so that the current cursor +row appears at a given vertical position relative to the array +view. By doing the following sequence of operations: ][*2 GetCursorSc][2 , +then reposition the cursor row, then ][*2 ScCursor][2 , you can achieve +cursor relocation while maintaining its visual location within +the array view.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 a][2 -|an integer describing the +vertical position of the cursor row (typically a number returned +by a previous call to ][*2 GetCursorSc][2 )]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:CenterCursor`(`): [@(0.0.255)2 void][2 _][*2 CenterCursor][2 ( +)]&] +[s0;l288; [2 Modifies the scrollbar position so that the current cursor +row appears in the middle of the array view.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollInto`(int`): [@(0.0.255)2 void][2 _][*2 ScrollInto][2 ( +][@(0.0.255)2 int][2 _][*@3;2 line][2 )]&] +[s0;l288; [2 Moves the scrollbar by the least possible amount in order +to make the given array row visible. When the given array row +is already visible, the function does nothing.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 line][2 -|zero`-based row index +of the array row to make visible]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollIntoCursor`(`): [@(0.0.255)2 void][2 _][*2 ScrollInto +Cursor][2 ()]&] +[s0;l288; [2 Moves the scrollbar by the least possible amount in order +to make the cursor row visible. This is equivalent to ][*2 ScrollInto(GetCursor())][2 . +]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetCursor`(`)const: [@(0.0.255)2 int][2 _][*2 GetCursor][2 () +_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the current vertical scrollbar position.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|Pixel position +of the vertical scrollbar. Position 0 is at the very top (the +top row of the array is fully visible).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:ScrollTo`(int`): [@(0.0.255)2 void][2 _][*2 ScrollTo][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 sc][2 )]&] +[s0;l288; [2 Moves the vertical array scrollbar to a given position.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 sc][2 -|Pixel position of the +scrollbar. The visible portion of the array can be obtained conceptually +by taking the stack of array rows with its top aligned at the +top of the view and moving it ][/2 sc][2 pixels upwards.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Find`(const Value`&`,int`,int`)const: [@(0.0.255)2 int][2 _ +][*2 Find][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v][2 , +][@(0.0.255)2 int][2 _][*@3;2 ii][2 _`=_][@3;2 0][2 , ][@(0.0.255)2 int][2 _][*@3;2 from][2 _`=_][@3;2 0 +][2 )_][@(0.0.255)2 const]&] +[s0;l288; [*C@3;2 v][2 -|value to look for in the given source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the source index to search]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 from][2 -|zero`-based row index +to start the search from]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based number +of the matched row, `-1 when none]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Find`(const Value`&`,const Id`&`,int`)const: [@(0.0.255)2 i +nt][2 _][*2 Find][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v][2 , +][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , ][@(0.0.255)2 int][2 _][*@3;2 from][2 _`=_][@3;2 0 +][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Locates the row (using linear search beginning at the +row ][/2 from][2 ) in which the source index value identified by +][/2 id][2 equals ][/2 val][2 . If such a row is found, the function +returns its zero`-based index. When not matched, the function +returns `-1.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|value to look for in the +given source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 from][2 -|zero`-based row index +to start the search from]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based number +of the matched row, `-1 when none]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:FindSetCursor`(const Value`&`,int`,int`): [@(0.0.255)2 b +ool][2 _][*2 FindSetCursor][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v +al][2 , ][@(0.0.255)2 int][2 _][*@3;2 ii][2 _`=_][@3;2 0][2 , ][@(0.0.255)2 int][2 _][*@3;2 from][2 _`= +_][@3;2 0][2 )]&] +[s0;l288; [2 Locates the row (using linear search beginning at the +row ][/2 from][2 ) in which the source index value identified by +its ordinal number ][/2 ii][2 equals ][/2 val][2 . If such a row is +found, the ][*2 SetCursor][2 is called automatically to move the +cursor to such a row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 val][2 -|value to look for in +the given source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based ordinal number +of the source index to search]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 from][2 -|zero`-based row index +to start the search from]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based number +of the matched row, `-1 when none]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:FindSetCursor`(const Value`&`,const Id`&`,int`): [@(0.0.255)2 b +ool][2 _][*2 FindSetCursor][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `&][2 _][*@3;2 v +al][2 , ][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 , ][@(0.0.255)2 int][2 _][*@3;2 from][2 _ +`=_][@3;2 0][2 )]&] +[s0;l288; [2 Locates the row (using linear search beginning at the +row ][/2 from][2 ) in which the source index value identified by +][/2 id][2 equals ][/2 val][2 . If such a row is found, the ][*2 SetCursor][2 +is called automatically to move the cursor to such a row.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 val][2 -|value to look for in +the given source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 from][2 -|zero`-based row index +to start the search from]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= the +desired row was found (and the cursor set), ][*2 false][2 when not]&] +[s0;0 &] +[s0;* &] +[s0; [* User interface elements]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:StdBar`(Bar`&`): [@(0.0.255)2 void][2 _][*2 StdBar][2 (][_^Bar^2 B +ar][@(0.0.255)2 `&][2 _][*@3;2 menu][2 )]&] +[s0;l288; [2 The default array local menu. The default local menu consists +of the standard editing actions (inserting / appending / duplicating +a row, editing a row, removing a row, moving a row, select all +rows) filtered by the array properties enabling / disabling the +various GUI elements (item insertion / deletion etc.). ]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 menu][2 -|the ][*2 Bar][2 object +representing the menu being generated]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsModified`(int`)const: [@(0.0.255)2 bool][2 _][*2 IsModifi +ed][2 (][@(0.0.255)2 int][2 _][*@3;2 ii][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Checks a source index in the currently edited row for +changes.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 ii][2 -|zero`-based row index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= the +index has been modified, ][*2 false][2 `= the index is in its original +state]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IsModified`(const Id`&`)const: [@(0.0.255)2 bool][2 _][*2 I +sModified][2 (][@(0.0.255)2 const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Checks a source index in the currently edited array row +for changes.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|source index identifier]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= the +source index has been modified, ][*2 false ][2 when not]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:StartEdit`(int`): [@(0.0.255)2 bool][2 _][*2 StartEdit][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 d][2 _`=_][@3;2 0][2 )]&] +[s0;l288; [2 Opens the current cursor row for editing and sets focus +to the ][/2 d][2 `-th column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 d][2 -|zero`-based column index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= editing +successfully initiated, ][*2 false][2 when not (when the array is +in ][*2 ReadOnly][2 mode or it has no editable columns)]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:GetEditColumn`(`)const: [@(0.0.255)2 int][2 _][*2 GetEditCo +lumn][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the column being currently edited.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|zero`-based index +of the column being edited, `-1 `= none]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoEdit`(`): [@(0.0.255)2 void][2 _][*2 DoEdit][2 ()]&] +[s0;l288; [2 Opens the current cursor row for editing.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoInsert`(int`): [@(0.0.255)2 void][2 _][*2 DoInsert][2 (][@(0.0.255)2 i +nt][2 _][*@3;2 cursor][2 )]&] +[s0;l288; [2 Begins the GUI insertion of a new row at a given location.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 cursor][2 -|zero`-based location +of the new row]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoInsertBefore`(`): [@(0.0.255)2 void][2 _][*2 DoInsertBefo +re][2 ()]&] +[s0;l288; [2 Begins the GUI insertion of a new row above the current +row.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoInsertAfter`(`): [@(0.0.255)2 void][2 _][*2 DoInsertAfter +][2 ()]&] +[s0;l288; [2 Begins the GUI insertion of a new row below the current +row.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoAppend`(`): [@(0.0.255)2 void][2 _][*2 DoAppend][2 ()]&] +[s0;l288; [2 Begins the GUI insertion of a new row at the end of the +array.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoRemove`(`): [@(0.0.255)2 virtual][2 +][@(0.0.255)2 bool][2 _][*2 DoRemove][2 ()]&] +[s0;l288; [2 Performs the GUI`-based removal of the current cursor +row. When the ][*2 AskRemove][2 property is set to ][*2 true][2 and +the user cancels the confirmation dialog, the function returns +][*2 false][2 and the current row is not removed.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row +has been removed successfully, ][*2 false][2 `= user has canceled +the row removal]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoDuplicate`(`): [@(0.0.255)2 void][2 _][*2 DoDuplicate][2 () +]&] +[s0;l288; [2 Duplicates the current row and opens it for editing.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:DoSelectAll`(`): [@(0.0.255)2 void][2 _][*2 DoSelectAll][2 () +]&] +[s0;l288; [2 Marks all array row as selected.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AcceptEnter`(`): [@(0.0.255)2 bool][2 _][*2 AcceptEnter][2 () +]&] +[s0;l288; [2 Performs all necessary GUI actions equivalent to when +the user presses the ][*2 Enter][2 key. The row being currently +edited is committed and, in the case it was a newly appended +line and the ][*2 NoInsertAppend][2 property is not set, an additional +row is added to the array and opened for editing.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= the +current row has been successfully committed, ][*2 false][2 when +not]&] +[s0;0 &] +[s0; &] +[s0; &] +[s0; [* Content export]&] +[s0;* &] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AsText`(String`(`*`)`(const Value`&`)`,bool`,const char`*`,const char`*`,const char`*`,const char`*`)const: [_^String^2 S +tring][2 _][*2 AsText][2 (][_^String^2 String][2 _(`*][*@3;2 format][2 )(][@(0.0.255)2 const][2 _Va +lue][@(0.0.255)2 `&][2 ), ][@(0.0.255)2 bool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 false][2 , +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 tab][2 _`=_`"`\t`", +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 row][2 _`=_`"`\r`\n`", +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 hdrtab][2 _`=_`"`\t`", +][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 hdrrow][2 _`=_`"`\r`\n`")_][@(0.0.255)2 c +onst]&] +[s0;l288; [2 Generic function for conversion of ArrayCtrl content to +text. The content visible on screen is exported (means, it exports +columns defined using AddColumn, not indicies). Cells are converted +to output format using ][*@3;2 format][2 function. If ][*@3;2 sel][2 +is true, only rows with IsSel true are exported. ][*@3;2 tab][2 +represents a separator text between cells in a row, ][*@3;2 row][2 +separator of rows. ][*@3;2 hdrtab][2 is separator of header cells +(those are texts of ArrayCtrl header) `- if NULL, no header is +exported. ][*@3;2 hdrrow][2 .is separator of header and data rows.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:SetClipboard`(bool`,bool`)const: [@(0.0.255)2 void][2 _][*2 S +etClipboard][2 (][@(0.0.255)2 bool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 false][2 , +][@(0.0.255)2 bool][2 _][*@3;2 hdr][2 _`=_][@(0.0.255)2 true][2 )_][@(0.0.255)2 const]&] +[s0;l288; [2 Puts ArrayCtrl content to clipboard in text format, `"`\t`" +and `"`\r`\n`" as separators. If ][*@3;2 sel][2 is true, only rows +with IsSel true are exported, ][*@3;2 hdr][2 controls whether header +is exported.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AsQtf`(bool`,bool`): [_^String^2 String][2 _][*2 AsQtf][2 (][@(0.0.255)2 b +ool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 false][2 , ][@(0.0.255)2 bool][2 _][*@3;2 hdr][2 _`=_][@(0.0.255)2 t +rue][2 )]&] +[s0;l288; [2 Returns ArrayCtrl content in QTF format. If ][*@3;2 sel][2 +is true, only rows with IsSel true are exported, ][*@3;2 hdr][2 +controls whether header is exported.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:AsCsv`(bool`,int`,bool`): [_^String^2 String][2 _][*2 AsCsv +][2 (][@(0.0.255)2 bool][2 _][*@3;2 sel][2 _`=_][@(0.0.255)2 false][2 , ][@(0.0.255)2 int][2 _][*@3;2 s +ep][2 _`=_`';`', ][@(0.0.255)2 bool][2 _][*@3;2 hdr][2 _`=_][@(0.0.255)2 true][2 )]&] +[s0;l288; [2 Returns ArrayCtrl content in csv format, using ][*@3;2 sep][2 +as separator. If ][*@3;2 sel][2 is true, only rows with IsSel true +are exported, ][*@3;2 hdr][2 controls whether header is exported.]&] +[s0; &] +[s0; &] +[s0; [* Notification callbacks]&] +[s0;0 &] +[s0; &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenLeftClick: [_^Callback^2 Callback][2 _][*2 WhenLeftClic +k]&] +[s0;l288; [2 This callback is called whenever the user clicks an array +cell.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenLeftDouble: [_^Callback^2 Callback][2 _][*2 WhenLeftDou +ble]&] +[s0;l288; [2 This callback is called whenever the user doubleclicks +an array cell.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenBar: [_^Callback1^2 Callback1][2 +_][*2 WhenBar]&] +[s0;l288; [2 This callback is called whenever the local array menu +has to be regenerated. By setting this callback to a different +function / method you can supply a custom local menu for the +array. The ][*2 Bar`&][2 argument is a reference to the menu to +be generated.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenEnterRow: [_^Callback^2 Callback][2 _][*2 WhenEnterRow]&] +[s0;l288; [2 This callback is called every time the cursor location +changes to a different row of the array.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenAcceptRow: [_^Gate^2 Gate][2 _][*2 WhenAcceptRow]&] +[s0;l288; [2 This gate is called every time an array row (open for +editing) needs to be validated. When the gate returns ][*2 false][2 , +the validation process is assumed to have failed, when it returns +][*2 true][2 , it is assumed to have succeeded. You can use this +callback to add your own validation algorithms relevant to the +array context within your application.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenUpdateRow: [_^Callback^2 Callback][2 _][*2 WhenUpdateRo +w]&] +[s0;l288; [2 This callback is called whenever an array row has been +updated. You can use this callback e.g. to project the changes +to a database or generally to an external data source.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenKillCursor: [_^Callback^2 Callback][2 _][*2 WhenKillCur +sor]&] +[s0;l288; [2 This callback is called whenever the cursor is moved away +from the table.]&] +[s0;l288; [*2 Note:][2 internally, when moving the cursor (e.g. by calling +the ][*2 SetCursor ][2 method), after committing the previous row +the cursor is removed from the table using ][*2 KillCursor][2 and +placed to the new location afterwards. Therefore every time the +cursor is moved, the ][*2 WhenKillCursor][2 callback is called as +a by`-product.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenCursor: [_^Callback^2 Callback][2 _][*2 WhenCursor]&] +[s0;l288; [2 This callback is called every time the cursor row number +changes (either when the cursor is removed from the table, or +when it has been moved to a different row).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenArrayAction: [_^Callback^2 Callback][2 _][*2 WhenArrayA +ction]&] +[s0;l288; [2 This callback is called every time the source array data +changes (typically after accepting changes to a certain row or +after deleting a row).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenStartEdit: [_^Callback^2 Callback][2 _][*2 WhenStartEdi +t]&] +[s0;l288; [2 This callback is called whenever the array row editing +process is initiated. It can be used e.g. to set up some additional +properties of the column editor objects, to fill in drop`-down +lists pertaining to certain column editors etc.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenAcceptEdit: [_^Callback^2 Callback][2 _][*2 WhenAcceptE +dit]&] +[s0;l288; [2 This callback is called whenever the currently edited +line has been committed.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenSelection: [_^Callback^2 Callback][2 _][*2 WhenSelectio +n]&] +[s0;l288; [2 This callback is called whenever the current array selection +changes. This includes changes to the cursor location as the +cursor is automatically considered part of the selection.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenCtrlsAction: [_^Callback^2 Callback][2 _][*2 WhenCtrlsA +ction]&] +[s0;l288; [2 This callback is called whenever some of the editor controls +constructed automatically via the column editing ][/2 factory][2 +calls its ][*2 WhenAction][2 method. It can be used to watch out +for changes in the cell editors and react to specific situations +accordingly.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenSel: [_^Callback^2 Callback][2 _][*2 WhenSel]&] +[s0;l288; [2 Called whenever cursor or selection changes.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenScroll: [_^Callback^2 Callback][2 _][*2 WhenScroll]&] +[s0;l288; [2 Called when scrolling of ArrayCtrl content happened.]&] +[s0;0 &] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:WhenHeaderLayout: [_^Callback^2 Callback][2 _][*2 WhenHeade +rLayout]&] +[s0;l288; [2 Called when header changes.]&] +[s0; &] +[s0; &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 ArrayCtrl`::IdInfo]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:struct: [@(0.0.255) struct]_[* IdInfo]&] +[s0;b42; [2 The ][*2 IdInfo][2 structure contains properties of all source +array indices. It can be used to set additional properties pertaining +to source array data.]&] +[s0;0 &] +[s0; &] +[ {{10000F(128)G(128)@1 [s0; [* Public Member List]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:InsertValue`(const Value`&`): [_^ArrayCtrl`:`:IdInfo^2 I +dInfo][@(0.0.255)2 `&][2 _][*2 InsertValue][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `& +][2 _][*@3;2 v][2 )]&] +[s0;l288; [2 The method sets up the default source index value for +newly created rows. This is used only when the row insertion +is GUI`-based (like using the ][*2 DoInsert][2 method for instance). +When a row is added to the array programmatically (e.g. using +][*2 Add][2 or ][*2 Insert][2 ), these default values are not used.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|default source index value]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:InsertValue`(ValueGen`&`): [_^ArrayCtrl`:`:IdInfo^2 I +dInfo][@(0.0.255)2 `&][2 _][*2 InsertValue][2 (][_^ValueGen^2 ValueGen][@(0.0.255)2 `&][2 _][*@3;2 g +][2 )]&] +[s0;l288; [2 The method sets up a factory for generating default index +values for newly created rows. This is used only when the row +insertion is GUI`-based (like using the ][*2 DoInsert][2 method +for instance). When a row is added to the array programmatically +(e.g. using ][*2 Add][2 or ][*2 Insert][2 ), the ][*2 InserValue][2 property +is not consulted.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 g][2 -|a reference to the value +generation factory. The ownership to the factory is not passed +by this call; the caller must insure the existence of the factory +object throughout the array duration.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:Accel`(int`(`*`)`(int`)`): [_^ArrayCtrl`:`:IdInfo^2 I +dInfo][@(0.0.255)2 `&][2 _][*2 Accel][2 (][@(0.0.255)2 int][2 _(`*][*@3;2 filter][2 )(][@(0.0.255)2 i +nt][2 ))]&] +[s0;l288; [2 This method sets up the source index accelerator function. +The accelerator is used to quickly locate rows using the keyboard +key presses.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 filter][2 -|a ][*2 CharFilter ][2 function +for keypress filtering]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:Accel`(`): [_^ArrayCtrl`:`:IdInfo^2 IdInfo][@(0.0.255)2 `& +][2 _][*2 Accel][2 ()]&] +[s0;l288; [2 This method sets up keyboard acceleration for the given +source index. The `'trivial`' ][/2 CharConvert][2 is used for character +translation.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:IdInfo`:`:GetInsertValue`(`): [_^Value^2 Value][2 _][*2 Get +InsertValue][2 ()]&] +[s0;l288; [2 Uses the ][*2 InsertValue][2 property to generate a new source +index value (either using a fixed default value or the value +creation factory).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|the generated value +to be used as the default for the newly inserted row.]&] +[s0;0 &] +[s0; &] +[s0; &] +[s0; &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 ArrayCtrl`::Column]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:class: [@(0.0.255) class]_[* Column]_:_[@(0.0.255) p +rivate]_[*@3 FormatConvert]&] +[s0;l288;2 &] +[s0; [%%/ Derived from][%% ]FormatConvert&] +[s0; &] +[s0; The [* ArrayCtrl`::Column] structure describes an output array +column. Its methods can be used to set or query its properties, +some of which are also settable via ArrayCtrl methods.&] +[s0;0 &] +[s0; &] +[ {{10000F(128)G(128)@1 [s0; [* Public Member List]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Add`(int`): [_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `& +][2 _][*2 Add][2 (][@(0.0.255)2 int][2 _][*@3;2 `_pos][2 )]&] +[s0;l288; [2 Adds another source data index to the list of source indices +used as the data for the given output column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 `_pos][2 -|zero`-based ordinal +number of the source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this][2 .]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Add`(const Id`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Add][2 (const ][_^Id^2 Id][2 `&_][*@3;2 id][2 )]&] +[s0;l288; [2 Adds another source data index to the list of source indices +used as the data for the given output column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|the ][*2 Id][2 identifier +of the source index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:AddIndex`(const Id`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 AddIndex][2 (][@(0.0.255)2 const][2 _][_^Id^2 Id][@(0.0.255)2 `&][2 _ +][*@3;2 id][2 )]&] +[s0;l288; [2 Adds another source index to the array and adds it to +the list of source indices bound to this output column. The newly +created index is assigned the given identifier.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 id][2 -|the identifier for the +newly created index]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:AddIndex`(`): [_^ArrayCtrl`:`:Column^2 Column +][@(0.0.255)2 `&][2 _][*2 AddIndex][2 ()]&] +[s0;l288; [2 Adds another source index to the array and adds it to +the list of source indices bound to this output column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:SetConvert`(const Convert`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 SetConvert][2 (][@(0.0.255)2 const][2 _][_^Convert^2 Convert][@(0.0.255)2 `& +][2 _][*@3;2 c][2 )]&] +[s0;l288; [2 Sets the ][*2 Convert][2 object for the given column. This +object is used to convert the source values (obtained from the +source data matrix) to the values displayable and/or editable +by the respective column display / editor object.]&] +[s0;l288; [*2 Note:][2 the ownership of the ][*2 Convert][2 object is not +transferred by this function. The array merely stores a pointer +to the Convert object. It is up to the host application to keep +the Convert object alive as long as necessary (until the ArrayCtrl +object is destroyed or all references to the Convert object obliterated +by new calls to the ][*2 SetConvert][2 method). In any case, most +Convert`-based object do not support copying at all; moreover, +as the Convert`-based objects are mostly derived from the basic +class, their copying is normally prone to slicing.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 c][2 -|a constant reference to +the Convert object to use for the given column]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:SetFormat`(const char`*`): [@(0.0.255)2 virtu +al][2 ][_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `&][2 _][*2 SetFormat][2 (][@(0.0.255)2 co +nst][2 _][@(0.0.255)2 char][2 _`*][*@3;2 fmt][2 )]&] +[s0;l288; [2 Sets the format string to use for the default value formatting. +When no Convert object is set for the column, the source value +is normally passed to the ][*2 NFormat][2 function where the ][/2 fmt][2 +argument defines the desired formatting pattern.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 fmt][2 -|a ][*2 NFormat][2 `-compatible +formatting pattern]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:SetDisplay`(const Display`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 SetDisplay][2 (][@(0.0.255)2 const][2 _][_^Display^2 Display][@(0.0.255)2 `& +][2 _][*@3;2 d][2 )]&] +[s0;l288; [2 Sets the default Display to use for this column. The column +Display can be overridden for certain array cells by calls to +the ][*^topic`:`/`/CtrlLib`/src`/ArrayCtrl`$en`-us`#`:`:ArrayCtrl`:`:SetDisplay`(int`,int`,const Display`&`)^2 A +rrayCtrl`::SetDisplay][2 method.]&] +[s0;l288; [*2 Note:][2 the ownership to the Display object is not transferred +by this function. The array merely stores a pointer to the Display; +it is up to the host application to keep the Display object alive +as long as necessary.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 d][2 -|a reference to the Display +object]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Edit`(Ctrl`&`): [_^ArrayCtrl`:`:Column^2 Colu +mn][@(0.0.255)2 `&][2 _][*2 Edit][2 (][_^Ctrl^2 Ctrl][@(0.0.255)2 `&][2 _][*@3;2 e][2 )]&] +[s0;l288; [2 Sets up the Ctrl`-based object to use for inline array +column editing.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 e][2 -|a reference to the editor +control object]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Ctrls`(Callback1``&`>`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Ctrls][2 (][_^Callback1^2 Callback1][2 <][_^One^2 One][2 <][_^Ctrl^2 C +trl][2 >`&>_][*@3;2 factory][2 )]&] +[s0;l288; [2 The methods sets up a factory which the ArrayCtrl uses +as necessary to create new Ctrl`'s for editing a given column. +The argument of this function is a callback, which, upon execution, +should allocate (normally using the ][*2 new][2 operator) the desired +editor object and set it to its argument. If the position of +Ctrl is equivalent to `'SetRect(0, 0, 0, 0)`', which is the default +value, Ctrl is resized to fit the ArrayCtrl cell accurately, +otherwise the position represents the position within the cell.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 factory][2 -|callback used for +new control creation]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Ctrls`(void`(`*`)`(One``&`)`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Ctrls][2 (][@(0.0.255)2 void][2 _(`*][*@3;2 factory][2 )(One +`&))]&] +[s0;l288; [2 This method sets up a factory which the ArrayCtrl uses +as necessary to create new Ctrl`'s for editing a given column. +The argument, a global function, is supposed to allocate a new +editor control (normally using the ][*2 new][2 operator) and set +it to its argument. If the position of Ctrl is equivalent to +`'SetRect(0, 0, 0, 0)`', which is the default value, Ctrl is +resized to fit the ArrayCtrl cell accurately, otherwise the position +represents the position within the cell. If the position of Ctrl +is equivalent to `'SetRect(0, 0, 0, 0)`', which is the default +value, Ctrl is resized to fit the ArrayCtrl cell accurately, +otherwise the position represents the position within the cell.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 factory][2 -|a global function +used for editor control creation]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Ctrls`(`): [@(0.0.255)2 template][2 _<][@(0.0.255)2 c +lass][2 _][*@4;2 T][2 >_][_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `&][2 _][*2 Ctrls][2 ()]&] +[s0;l288; [2 This member template sets up a default factory for creating +editor controls of a given type. Every time the ArrayCtrl needs +to create a new editor control, an object of the type ][*2 T][2 +is created automatically (using the ][*2 new][2 operator). If the +position of Ctrl is equivalent to `'SetRect(0, 0, 0, 0)`', which +is the default value, Ctrl is resized to fit the ArrayCtrl cell +accurately, otherwise the position represents the position within +the cell.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@4;2 T][2 -|the desired object editor +type ]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:InsertValue`(const Value`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 InsertValue][2 (][@(0.0.255)2 const][2 _][_^Value^2 Value][@(0.0.255)2 `& +][2 _][*@3;2 v][2 )]&] +[s0;l288; [2 Instructs the ArrayCtrl object to initialize this column +in newly created rows to the given value ][/2 v][2 . (This applies +only to GUI`-based row insertion using methods like ][*2 DoInsert][2 +etc., the low`-level, programmer`-controlled row insertion methods +like ][*2 Add][2 or ][*2 Insert][2 always initialize the source data +matrix with ][*2 Null][2 `'s).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 v][2 -|the value to use as the +default for newly inserted rows]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:InsertValue`(ValueGen`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 InsertValue][2 (][_^ValueGen^2 ValueGen][@(0.0.255)2 `&][2 _][*@3;2 g +][2 )]&] +[s0;l288; [2 Programs the ArrayCtrl object to use the given ][*2 ValueGen][2 +factory for default value generation for newly created rows. +This can be used e.g. to generate unique UUID`'s or primary keys +using an Oracle SEQUENCE object for a primary key column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 g][2 -|a reference to the ValueGen +object used for default value generation]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:NoClickEdit`(`): [_^ArrayCtrl`:`:Column^2 Col +umn][@(0.0.255)2 `&][2 _][*2 NoClickEdit][2 ()]&] +[s0;l288; [2 Disables entering the editing mode when clicking the respective +column.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Cache`(`): [_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `& +][2 _][*2 Cache][2 ()]&] +[s0;l288; [2 Enables using the cache to store the converted values +of this column. By default, converted value caching is turned +off to make cell value conversion entirely dynamic; however, +very often it is advisable to enable using the cache, especially +when the conversion is relatively slow (for instance, when the +conversion queries a database connection to convert the value).]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Accel`(int`(`*`)`(int`)`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Accel][2 (][@(0.0.255)2 int][2 _(`*][*@3;2 filter][2 )(][@(0.0.255)2 i +nt][2 ))]&] +[s0;l288; [2 Sets up the accelerator for the given column. A given +filtering function is used to convert keystrokes before acceleration.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 filter][2 -|a ][*2 CharConvert][2 `-style +function to use for keystroke conversion]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Accel`(`): [_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `& +][2 _][*2 Accel][2 ()]&] +[s0;l288; [2 Sets up the accelerator for the given column. No keystroke +conversion is performed.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Margin`(int`): [_^ArrayCtrl`:`:Column^2 Colum +n][@(0.0.255)2 `&][2 _][*2 Margin][2 (][@(0.0.255)2 int][2 _][*@3;2 m][2 )]&] +[s0;l288; [2 Sets up the margin width for the given column. This is +equivalent to calling the ][*^topic`:`/`/CtrlLib`/src`/HeaderCtrl`$en`-us`#`:`:HeaderCtrl`:`:Column`:`:SetMargin`(int`)^2 S +etMargin][2 method of the underlying ][*2 HeaderTab][2 .]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 m][2 -|]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 `*this]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Sorting`(const ValueOrder`&`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Sorting][2 (][@(0.0.255)2 const][2 _][_^ValueOrder^2 ValueOrder][@(0.0.255)2 `& +][2 _][*@3;2 o][2 )]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Sorting`(int`(`*`)`(const Value`&a`,const Value`&b`)`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Sorting][2 (][@(0.0.255)2 int][2 _(`*][*@3;2 c][2 )(][@(0.0.255)2 co +nst][2 _Value][@(0.0.255)2 `&][2 _a, ][@(0.0.255)2 const][2 _Value][@(0.0.255)2 `&][2 _b))]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Sorting`(`): [_^ArrayCtrl`:`:Column^2 Column][@(0.0.255)2 `& +][2 _][*2 Sorting][2 ()]&] +[s0;l288; [2 Activates sorting of ArrayCtrl column by clicking on its +header tab. Parameterless version uses default Value ordering +using StdValueCompare.]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:SortDefault`(`): [_^ArrayCtrl`:`:Column^2 Col +umn][@(0.0.255)2 `&][2 _][*2 SortDefault][2 ()]&] +[s0;l288; [2 Sets this column to be initial sorting column (calls SetSortColumn +of ArrayCtrl).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:HeaderTab`(`): [_^HeaderCtrl`:`:Column^2 Head +erCtrl`::Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 ()]&] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:HeaderTab`(`)const: [@(0.0.255)2 const][2 _][_^HeaderCtrl`:`:Column^2 H +eaderCtrl`::Column][@(0.0.255)2 `&][2 _][*2 HeaderTab][2 ()_][@(0.0.255)2 const]&] +[s0;l288; [2 Returns the ][*2 HeaderCtrl`::Column][2 object describing +the given column. This object can be used to set up additional +column properties (like column width constraints or the ][*^topic`:`/`/CtrlLib`/src`/HeaderCtrl`$en`-us`#`:`:HeaderCtrl`:`:Column`:`:Callback WhenAction^2 W +henAction][2 callback).]&] +[s0;0 &] +[s0;H6;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Column`:`:Tip`(const char`*`): [_^ArrayCtrl`:`:Column^2 C +olumn][@(0.0.255)2 `&][2 _][*2 Tip][2 (][@(0.0.255)2 const][2 _][@(0.0.255)2 char][2 _`*][*@3;2 tip +][2 )]&] +[s0;l288; [2 Assigns a ][*@3;2 tip][2 to header tab column.]&] +[s0;0 &] +[s0; &] +[ {{10000t/25b/25@3 [s0; [*@(229)4 ArrayCtrl`::Order]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Order`:`:struct: [@(0.0.255) struct]_[* Order]&] +[s0;b42; [2 The ][*2 Order][2 object is used for array row sorting. The +overloaded ][*2 operator ()][2 acts as the sorting predicate, which +is consulted within the sorting method to determine which of +a given pair of row is `'less`' according to the desired sorting.]&] +[s0;0 &] +[s0; &] +[ {{10000F(128)G(128)@1 [s0; [* Public Member List]]}}&] +[s0;0 &] +[s0;i448;a25;kKO9;:ArrayCtrl`:`:Order`:`:operator`(`)`(const Vector``&`,const Vector``&`)const: [@(0.0.255)2 v +irtual][2 ][@(0.0.255)2 bool][2 _][*2 operator()][2 (][@(0.0.255)2 const][2 _][_^Vector^2 Vector +][2 <][_^Value^2 Value][2 >`&_][*@3;2 row1][2 , ][@(0.0.255)2 const][2 _][_^Vector^2 Vector][2 <][_^Value^2 V +alue][2 >`&_][*@3;2 row2][2 )_][@(0.0.255)2 const][2 _`=_][@3;2 0]&] +[s0;l288; [2 The sorting predicate. This method should return ][*2 true][2 +when its first argument (][/2 row1][2 ) is less than the second argument +(][/2 row2][2 ) according to the desired ordering.]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 row1][2 -|an array of source data +index values for the first of the rows to compare]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*C@3;2 row2][2 -|an array of source data +index values for the other row to compare]&] +[s0;l288;i1121;b17;O9;~~~.1408; [*/2 Return value][2 -|][*2 true][2 `= row1 +< row2, ][*2 false][2 `= row1 >`= row2]&] +[s0;0 &] +[s0; ]] \ No newline at end of file diff --git a/rainbow/guiplatform.h b/rainbow/guiplatform.h index 6862e5b77..8f5e17533 100644 --- a/rainbow/guiplatform.h +++ b/rainbow/guiplatform.h @@ -47,6 +47,12 @@ #define GUIPLATFORM_INCLUDE #endif +#ifdef flagSLAVEGUI +#define GUIPLATFORM_KEYCODES_INCLUDE +//need to make SDL_keysym.h known before K_ enum +#define GUIPLATFORM_INCLUDE +#endif + #ifdef flagTELPP #define GUIPLATFORM_KEYCODES_INCLUDE //need to make SDL_keysym.h known before K_ enum