From f67791b6d615b72b60b590371550f72a6794393c Mon Sep 17 00:00:00 2001 From: ketmar Date: Tue, 17 Apr 2018 06:40:32 +0000 Subject: [PATCH] it is now possible to open and close groups in contact list FossilOrigin-Name: 1647b4db836ae3895ffed67b73d400f345b05c8efdb8bc7409217c8978e3d130 --- accobj.d | 19 ++++++++------ tkclist.d | 88 +++++++++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 74 insertions(+), 33 deletions(-) diff --git a/accobj.d b/accobj.d index 11cb77e..32f3011 100644 --- a/accobj.d +++ b/accobj.d @@ -108,11 +108,6 @@ public: if (serialize(info, diskFileName)) mDirty = false; } - // save if dirty - void update () { - if (mDirty) save(); - } - @property bool visible () const nothrow @trusted @nogc { if (!hideIfNoVisibleMembers) return true; // always visible // check if we have any visible members @@ -314,11 +309,11 @@ public: @property bool visible () const nothrow @trusted @nogc { if (kfd) return false; - if (acceptPending || requestPending || optShowOffline) return true; + if (acceptPending || requestPending) return true; if (unreadCount > 0) return true; - if (!showOffline && status == ContactStatus.Offline) return false; + if (!showOffline && !optShowOffline && status == ContactStatus.Offline) return false; auto grp = acc.groupById(gid); - return grp.visible; + return (grp.visible && grp.opened); } @property nothrow @safe { @@ -566,6 +561,12 @@ public: glist.serialize(basePath~"contacts/groups.rc"); } + void saveUpdatedGroups () { + bool needToUpdate = false; + foreach (Group g; groups) if (g.mDirty) { needToUpdate = true; g.mDirty = false; } + if (needToUpdate) saveGroups(); + } + private: ContactStatus mStatus = ContactStatus.Offline; @@ -617,10 +618,12 @@ public: void processResendQueue () { if (!isOnline) return; foreach (Contact ct; contacts.byValue) { ct.processResendQueue(); ct.update(); } + saveUpdatedGroups(); } void saveResendQueue () { foreach (Contact ct; contacts.byValue) { ct.saveResendQueue(); ct.update(); } + saveUpdatedGroups(); } private: diff --git a/tkclist.d b/tkclist.d index f901a56..f4f8e0d 100644 --- a/tkclist.d +++ b/tkclist.d @@ -61,10 +61,10 @@ private extern(C) const(char)[] xfmt (const(char)* fmt, ...) { // ////////////////////////////////////////////////////////////////////////// // class ListItemBase { private: - this () {} + this (CList aowner) { owner = aowner; } protected: - bool mVisible = true; + CList owner; public: @property Account ownerAcc () => null; @@ -75,10 +75,10 @@ public: void setSmallFont () { fstash.fontId = "ui"; fstash.size = 15; } @property int height () => cast(int)fstash.fontHeight; - @property bool visible () => mVisible; + @property bool visible () => true; - bool onMouse (MouseEvent event) => false; // true: eaten; will modify fstash - bool onKey (KeyEvent event) => false; // true: eaten; will modify fstash + bool onMouse (MouseEvent event, bool meActive) => false; // true: eaten; will modify fstash + bool onKey (KeyEvent event, bool meActive) => false; // true: eaten; will modify fstash protected void drawPrepare (NVGContext nvg) { setFont(); @@ -97,7 +97,7 @@ public: Account acc; public: - this (Account aAcc) { assert(aAcc !is null); acc = aAcc; } + this (CList aowner, Account aAcc) { assert(aAcc !is null); acc = aAcc; super(aowner); } override @property Account ownerAcc () => acc; @@ -134,12 +134,23 @@ public: Group group; public: - this (Group aGroup) { assert(aGroup !is null); group = aGroup; } + this (CList aowner, Group aGroup) { assert(aGroup !is null); group = aGroup; super(aowner); } override @property Account ownerAcc () => group.acc; override @property bool visible () => group.visible; + // true: eaten + override bool onMouse (MouseEvent event, bool meActive) { + if (event == "LMB-Down") { + //conwriteln("!!! ", group.opened); + group.opened = !group.opened; + glconPostScreenRepaint(); + return true; + } + return false; + } + override void drawAt (NVGContext nvg, int x0, int y0, int wdt, bool selected=false) { drawPrepare(nvg); @@ -163,7 +174,7 @@ public: Contact ct; public: - this (Contact aCt) { assert(aCt !is null); ct = aCt; } + this (CList aowner, Contact aCt) { assert(aCt !is null); ct = aCt; super(aowner); } override @property Account ownerAcc () => ct.acc; @@ -179,6 +190,17 @@ public: return max(cast(int)hgt, 16); } + // true: eaten + override bool onMouse (MouseEvent event, bool meActive) { + if (event == "LMB-Down") { + owner.activeItem = this; + if (owner.onActivateContactCB !is null) owner.onActivateContactCB(ct); + glconPostScreenRepaint(); + return true; + } + return false; + } + override void drawAt (NVGContext nvg, int x0, int y0, int wdt, bool selected=false) { import std.algorithm : max; @@ -291,10 +313,6 @@ public: public: this () {} - @property int activeItemIndex () const pure nothrow @safe @nogc => mActiveItem; - - void resetActiveItem () nothrow @safe @nogc { mActiveItem = -1; } - // the first one is "main"; can return `null` Account mainAccount () { foreach (ListItemBase li; items) if (auto lc = cast(ListItemAccount)li) return lc.acc; @@ -346,11 +364,11 @@ public: mActiveItem = -1; mTopY = 0; removeAccount(acc); - items ~= new ListItemAccount(acc); + items ~= new ListItemAccount(this, acc); Contact[] css; scope(exit) delete css; foreach (Group g; acc.groups) { - items ~= new ListItemGroup(g); + items ~= new ListItemGroup(this, g); css.length = 0; css.assumeSafeAppend; foreach (Contact c; acc.contacts.byValue) if (c.gid == g.gid) css ~= c; @@ -367,7 +385,7 @@ public: } return (s0.length < s1.length); }); - foreach (Contact c; css) items ~= new ListItemContact(c); + foreach (Contact c; css) items ~= new ListItemContact(this, c); } } @@ -422,6 +440,32 @@ public: return res; } + final void resetActiveItem () nothrow @safe @nogc { mActiveItem = -1; } + + final @property int activeItemIndex () const pure nothrow @safe @nogc => mActiveItem; + + final @property void activeItemIndex (int idx) nothrow @trusted { + if (idx < 0 || idx >= items.length) idx = -1; + if (mActiveItem == idx) return; + mActiveItem = idx; + try { glconPostScreenRepaint(); } catch (Exception e) {} // sorry + } + + final @property inout(ListItemBase) activeItem () inout pure nothrow @trusted @nogc { + pragma(inline, true); + return (mActiveItem >= 0 && mActiveItem < items.length ? cast(inout)items[mActiveItem] : null); + } + + final @property void activeItem (ListItemBase it) nothrow @trusted { + int idx = -1; + if (it !is null) { + foreach (immutable ii, const ListItemBase li; items) { + if (li is it) { idx = cast(int)ii; break; } + } + } + activeItemIndex = idx; + } + // if called with `null` ct, deactivate void delegate (Contact ct) onActivateContactCB; @@ -431,16 +475,10 @@ public: int mx = event.x-mLastX; int my = event.y-mLastY; if (mx < 0 || my < 0 || mx >= mLastWidth || my >= mLastHeight) return false; - if (event == "LMB-Down") { - int it = itemAtY(my); - if (it >= 0 && it != mActiveItem) { - if (auto ci = cast(ListItemContact)items[it]) { - mActiveItem = it; - if (onActivateContactCB !is null) onActivateContactCB(ci.ct); - glconPostScreenRepaint(); - } - } - return true; + + int it = itemAtY(my); + if (it >= 0) { + if (items[it].onMouse(event, it == mActiveItem)) return true; } enum ScrollHeight = 32; -- 2.11.4.GIT