Skip to content

Commit

Permalink
Add support for switching between tree contents
Browse files Browse the repository at this point in the history
The tree gadget now supports caching of multiple lists of items. When
adding items to a tree list, an ID is now returned, which can be used
at a later date to display that list of items. This allows dynamic
switching between the cached lists.
  • Loading branch information
Colin Ward authored and hitman-codehq committed Mar 16, 2024
1 parent acbf055 commit 3c9ad8a
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 27 deletions.
126 changes: 106 additions & 20 deletions StdGadgetTree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,10 @@ static struct ColumnInfo g_columnInfo[] =
* up upon failure.
*
* @date Sunday 18-Jul-2021 12:32 pm, Am Theater Stralsund FeWo
* @param a_title Title to be displayed at the top of the tree's column
* @return KErrNone if successful, else KErrNoMemory
*/

int CStdGadgetTree::construct(const std::string &a_title)
int CStdGadgetTree::construct()
{
int retVal = KErrNone;

Expand All @@ -43,10 +42,6 @@ int CStdGadgetTree::construct(const std::string &a_title)

#ifdef __amigaos__

/* For Amiga OS the title string is not copied by the native gadget, so we copy it into our own persistent memory */
/* before assigning it to the tree */
m_title = a_title;

if (!createNative())
{
retVal = KErrNoMemory;
Expand All @@ -56,16 +51,14 @@ int CStdGadgetTree::construct(const std::string &a_title)

/* Initialise the Qt specific helper object */
m_poGadget = &m_tree;
m_tree.construct(a_title);
m_tree.construct("");

// TODO: CAW - Why aren't these fetched automatically in CStdGadget?
m_iWidth = m_poGadget->width();
m_iHeight = m_poGadget->height();

#else /* ! QT_GUI_LIB */

(void) a_title;

m_poParentLayout->Attach(this);

#endif /* ! QT_GUI_LIB */
Expand All @@ -80,6 +73,34 @@ int CStdGadgetTree::construct(const std::string &a_title)
return retVal;
}

/**
* CStdGadgetTree Destructor.
* Frees all lists of items in the map of available lists.
*
* @date Wednesday 13-Mar-2024 6:45 am, Code HQ Tokyo Tsukuda
*/

CStdGadgetTree::~CStdGadgetTree()
{

#ifdef __amigaos__

/* Iterate through the map of available lists and delete the nodes from each one */
for (auto &item : m_itemsMap)
{
List &list = item.second;
CTreeNode *node;

while ((node = reinterpret_cast<CTreeNode *>(RemHead(&list))) != NULL)
{
FreeListBrowserNode(reinterpret_cast<struct Node *>(node));
}
}

#endif /* __amigaos__ */

}

#ifdef __amigaos__

/**
Expand Down Expand Up @@ -143,22 +164,79 @@ std::string CStdGadgetTree::getSelectedItem()
}

/**
* Sets the contents of the tree gadget.
* This method accepts a list of CTreeNode items, with each instance containing a text string that will
* be used to add a node to the tree.
* Sets the content of the tree gadget.
* This method accepts an integer identifier that represents a list of items that have been previously added to the
* tree. It will remove the current set of items and replace them will the ones represented by the identifier. This
* enables switching between multiple different sets of items.
*
* All content IDs have a value of >= 1. If the special value of 0 is passed in, the contents of the tree gadget are
* set to empty.
*
* @date Saturday 24-Feb-2024 6:25 am, Code HQ Tokyo Tsukuda
* @param a_contentID A content ID identifier, returned from setContent(StdList<CTreeNode> &)
*/

void CStdGadgetTree::setContent(int a_contentID)
{
ASSERTM((a_contentID >= 0), "CStdGadgetTree::setContent() => Invalid content ID passed in");

#ifdef __amigaos__

if (a_contentID == 0)
{
SetGadgetAttrs((struct Gadget *) m_poGadget, NULL, NULL, LISTBROWSER_Labels, (ULONG) NULL, TAG_DONE);
}
else
{
ULONG items = (ULONG) &m_itemsMap[a_contentID];

SetGadgetAttrs((struct Gadget *) m_poGadget, m_poParentWindow->m_poWindow, NULL, LISTBROWSER_Labels, items, TAG_DONE);
}

#elif defined(QT_GUI_LIB)

while (static_cast<QTreeWidget *>(m_poGadget)->takeTopLevelItem(0)) { }

if (a_contentID != 0)
{
static_cast<QTreeWidget *>(m_poGadget)->insertTopLevelItems(0, m_itemsMap[a_contentID]);
}

#else /* ! QT_GUI_LIB */

(void) a_contentID;

#endif /* ! QT_GUI_LIB */

}

/**
* Sets the content of the tree gadget.
* This method accepts a list of CTreeNode items, with each item containing a text string that will be used to
* add a node to the tree.
*
* The items passed in will be converted to a format suitable for the underlying native tree gadget, and the original
* list is no longer required and can be disposed of. This method can be called multiple times and a new internal
* list will be created each time. An integer identifier representing that list will be returned, which can be used
* to switch between lists using setContent(int).
*
* @date Monday 13-Sep-2021 8:53 am, Code HQ Bergmannstrasse
* @param a_items The list of items to be added to the tree
* @return An identifier that represents the content that was just added
*/

void CStdGadgetTree::setContent(StdList<CTreeNode> &a_items)
int CStdGadgetTree::setContent(StdList<CTreeNode> &a_items)
{

#ifdef __amigaos__

/* Any previously added item list must be detached from the list browser gadget before being updated */
SetGadgetAttrs((struct Gadget *) m_poGadget, NULL, NULL, LISTBROWSER_Labels, (ULONG) NULL, TAG_DONE);

struct List &fileList = m_itemsMap[m_nextContentID];

NewList(&fileList);

/* Iterate through the list passed in and, for each item on the list, create a list browser node to represent */
/* it, and add it to the list browser's list of nodes */
CTreeNode *treeNode = a_items.getHead();
Expand All @@ -170,14 +248,14 @@ void CStdGadgetTree::setContent(StdList<CTreeNode> &a_items)
if ((node = AllocListBrowserNode(1, LBNCA_CopyText, TRUE, LBNCA_Text, (ULONG) treeNode->m_text.c_str(),
TAG_DONE)) != nullptr)
{
AddTail(&m_fileList, node);
AddTail(&fileList, node);
}

treeNode = a_items.getSucc(treeNode);
}

/* Re-add the updated list of items to the list browser gadget */
SetGadgetAttrs((struct Gadget *) m_poGadget, m_poParentWindow->m_poWindow, NULL, LISTBROWSER_Labels, (ULONG) &m_fileList, TAG_DONE);
SetGadgetAttrs((struct Gadget *) m_poGadget, m_poParentWindow->m_poWindow, NULL, LISTBROWSER_Labels, (ULONG) &fileList, TAG_DONE);

#elif defined(QT_GUI_LIB)

Expand All @@ -196,12 +274,15 @@ void CStdGadgetTree::setContent(StdList<CTreeNode> &a_items)
/* Add the new list of items to the tree widget */
static_cast<QTreeWidget *>(m_poGadget)->insertTopLevelItems(0, items);

m_itemsMap.emplace(m_nextContentID, items);

#else /* ! QT_GUI_LIB */

(void) a_items;

#endif /* ! QT_GUI_LIB */

return m_nextContentID++;
}

/**
Expand All @@ -217,12 +298,17 @@ void CStdGadgetTree::setTitle(const std::string &a_title)

#ifdef __amigaos__

/* For Amiga OS the title string is not copied by the native gadget, so we copy it into our own persistent memory */
/* before assigning it to the tree */
m_title = a_title;
g_columnInfo[0].ci_Title = (STRPTR) m_title.c_str();
/* Only set the title if it is actually different */
if (m_title != a_title)
{
/* For Amiga OS the title string is not copied by the native gadget, so we copy it into our own persistent memory */
/* before assigning it to the tree */

m_title = a_title;
g_columnInfo[0].ci_Title = (STRPTR) m_title.c_str();

SetGadgetAttrs((struct Gadget *) m_poGadget, NULL, NULL, LISTBROWSER_ColumnInfo, (ULONG) g_columnInfo, TAG_DONE);
SetGadgetAttrs((struct Gadget *) m_poGadget, m_poParentWindow->m_poWindow, NULL, LISTBROWSER_ColumnInfo, (ULONG) g_columnInfo, TAG_DONE);
}

#elif defined(QT_GUI_LIB)

Expand Down
35 changes: 28 additions & 7 deletions StdGadgets.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

/** @file */

#include <map>

#ifdef __amigaos__

#include <intuition/classes.h>
Expand All @@ -25,6 +27,14 @@ class QBoxLayout;
class QLabel;
class QWidget;

#ifdef __amigaos__

/* A typedef to make usage of the map of item lists easier */

typedef std::map<int, List> ItemsMap;

#endif /* __amigaos__ */

/* Types of gadgets that can be created */

enum TStdGadgetType
Expand Down Expand Up @@ -402,14 +412,18 @@ class CStdGadgetTree : public CStdGadget
{
private:

int m_nextContentID; /**< The next content ID that will be assigned to a new list */

#ifdef __amigaos__

std::string m_title; /**< Persistent memory for the title string passed in */
List m_fileList; /**< List of items in the tree */
std::string m_title; /**< Persistent memory for the title string passed in */
struct List m_fileList; /**< Initial empty list of items in the tree */
ItemsMap m_itemsMap; /**< Map of the lists of items that can be displayed by the tree */

#elif defined(QT_GUI_LIB)

CQtGadgetTree m_tree; /**< Helper class for listening for signals */
CQtGadgetTree m_tree; /**< Helper class for listening for signals */
std::map<int, QList<QTreeWidgetItem *>> m_itemsMap; /**< Map of the lists of items that can be displayed by the tree */

#endif /* QT_GUI_LIB */

Expand All @@ -426,10 +440,13 @@ class CStdGadgetTree : public CStdGadget
#endif /* ! QT_GUI_LIB */

{
m_iGadgetType = EStdGadgetTree;
m_iGadgetID = a_gadgetID;
m_poParentLayout = a_parentLayout;
m_poParentWindow = a_parentLayout->GetParentWindow();
m_iGadgetID = a_gadgetID;
m_iGadgetType = EStdGadgetTree;

/* A content ID with a value of 0 has the special meaning of "remove content", so valid content IDs start at 1 */
m_nextContentID = 1;

#ifdef __amigaos__

Expand All @@ -439,15 +456,19 @@ class CStdGadgetTree : public CStdGadget

}

int construct(const std::string &a_title);
~CStdGadgetTree();

int construct();

bool createNative();

int setContent(StdList<CTreeNode> &a_items);

public:

std::string getSelectedItem();

void setContent(StdList<CTreeNode> &a_items);
void setContent(int a_contentID);

void setTitle(const std::string &a_title);

Expand Down

0 comments on commit 3c9ad8a

Please sign in to comment.