#include "precomp.h" #include "itemlistwnd.h" #include "../../common/metatags.h" #include "../../studio/api.h" #include "../skinclr.h" #include "../../common/filename.h" #include "../../common/dragitemi.h" #include "../../common/contextmenu.h" #define NIFTY_OUTLINE static SkinColor current("wasabi.itemlist.outline.current"); static SkinColor selborder("wasabi.itemlist.selborder"); static SkinColor focus("wasabi.itemlist.outline.focus"); ItemListColumn_MetaTag::ItemListColumn_MetaTag(const char *newtag, int centered, const char *label) : ItemListColumn() { if (label == NULL) label = newtag; setLabel(label); tag = newtag; center = centered; datatype = api->metadb_getMetaDataType(tag); } ItemListColumn_Callback::ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const char *name) : ItemListColumn(name) { parent = _parent; lparam = _lparam; } void ItemListColumn_Callback::render(int pos, const char *playstring, Canvas &c, RECT &r) { parent->userRender(pos, playstring, c, r, lparam); } void ItemListColumn_Callback::columnToText(int pos, const char *playstring, char *str, int maxlen) { parent->userColumnToText(pos, playstring, lparam, str, maxlen); } void ItemListColumn_MetaTag::render(int pos, const char *playstring, Canvas &canvas, RECT &r) { char buf[4096]=""; if (api->metadb_getMetaData(playstring, tag, buf, 4096) <= 1) return; api->metadb_renderData(&canvas, r, buf, datatype, center); } void ItemListColumn_MetaTag::columnToText(int pos, const char *playstring, char *str, int maxlen) { api->metadb_getMetaData(playstring, tag, str, maxlen); } const char *ItemListColumn_MetaTag::getTag() { return tag; } void ItemListColumn_Numbered::render(int pos, const char *playstring, Canvas &c, RECT &r) { StringPrintf buf("%d.", pos+1); c.textOutEllipsed(r.left, r.top, r.right - r.left, r.bottom-r.top, buf); } void ItemListColumn_Numbered::columnToText(int pos, const char *playstring, char *str, int maxlen) { StringPrintf buf("%d", pos+1); STRNCPY(str, buf, maxlen); } ItemListWnd::ItemListWnd() { keep = NULL; item_invalidate_border++; } ItemListWnd::~ItemListWnd() { api->syscb_deregisterCallback(static_cast(this)); } int ItemListWnd::onInit() { ITEMLISTWND_PARENT::onInit(); api->syscb_registerCallback(static_cast(this)); return 1; } int ItemListWnd::insertColumn(ItemListColumn *column, int width, int pos) { column->setWidth(width); return ITEMLISTWND_PARENT::insertColumn(column, pos); } int ItemListWnd::onBeginDrag(int iItem) { if (!wantAutoDrag()) return ITEMLISTWND_PARENT::onBeginDrag(iItem); // add all the entries int n, i, c = 0; n = getNumItems(); if (n == 0) return 0; // empty list ASSERT(keep == NULL); keep = new PtrList(); // count up the items for (i = 0; i < n; i++) { if (getItemSelected(i)) { // expose all the pointers we can LPARAM lparam = getItemData(i); if (!addMoreDragTypes(i)) { FilenameNC *fn = keep->addItem(new FilenameNC(convertlParam(lparam))); addDragItem(DD_FILENAME, static_cast(fn)); } c++; } } if (keep->getNumItems() == 0 || c <= 0) { delete keep; keep = NULL; return 0; } handleDrag(); return 1; } int ItemListWnd::dragComplete(int success) { ASSERT(keep != NULL); keep->deleteAll(); delete keep; keep = NULL; return 1; } int ItemListWnd::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) { const char *playstring = convertlParam(lParam); if (playstring == NULL) return 0; COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam); COLORREF fgcolor = getTextColor(lParam); int iscur = getSelected(lParam); RECT box; canvas->getClipBox(&box); if (!getBgBitmap()) { RECT r2 = *r; r2.left = box.left; RegionI *reg = new RegionI(&r2); canvas->selectClipRgn(reg); delete reg; canvas->fillRect(r, getBgColor()); } canvas->setTextColor(fgcolor); // ASSERT(cols.getNumItems() == getNumColumns()); if (isselected) { RECT mr = *r; canvas->fillRect(&mr, bgcolor); /*au gratin potatoes/broccoli chicken^2 salad, croutons, cheese, ranch fries */ #ifdef NIFTY_OUTLINE int prevsel = getItemSelected(pos-1); int nextsel = getItemSelected(pos+1); mr.bottom--; canvas->pushPen(selborder); canvas->lineDraw(mr.left, mr.top, mr.left, mr.bottom); canvas->lineDraw(mr.right-1, mr.top, mr.right-1, mr.bottom); if (!prevsel) canvas->lineDraw(mr.left, mr.top, mr.right, mr.top); if (!nextsel) canvas->lineDraw(mr.left, mr.bottom, mr.right, mr.bottom); canvas->popPen(); #endif } if (isfocused || iscur) { int pentype = isfocused ? FALSE : TRUE; int boxcolor = iscur ? current : focus; canvas->drawRect(r, pentype, boxcolor); } canvas->pushTextSize(getFontSize()); int x = 1+r->left; for (int i = 0; i < getNumColumns(); i++) { ItemListColumn *col = (ItemListColumn *)enumListColumn(i); RECT ir; ir.left = x; ir.right = x + getColumnWidth(i); ir.top = r->top; ir.bottom = r->bottom; if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) { col->render(pos, playstring, *canvas, ir); } x = ir.right; } canvas->popTextSize(); return 1; } void ItemListWnd::convertlParamColumn(int col, int pos, LPARAM param, char *str, int maxlen) { ASSERT(str != NULL); ItemListColumn *cl = (ItemListColumn *)enumListColumn(col); const char *playstring = convertlParam(param); cl->columnToText(pos, playstring, str, maxlen); } int ItemListWnd::onContextMenu(int x, int y) { PtrList filenames; DragItemI *dragitem = NULL; if ((dragitem = itemlistwnd_getDragItem(x, y)) == NULL) { DragItemT *di = new DragItemT; int n = getNumItems(); for (int i = 0; i < n; i++) { if (getItemSelected(i)) { LPARAM lparam = getItemData(i); const char *playstring = convertlParam(lparam); di->addDatum(filenames.addItem(new FilenameNC(playstring))); } } dragitem = di; } ContextMenu cm(this, filenames.getNumItems() ? dragitem : NULL, false); PtrList drags; for (int i = 0; ; i++) { DragItemI *aitem = itemlistwnd_getSecondDragItem(i); if (aitem == NULL) break; drags.addItem(aitem); if (cm.getNumCommands()) cm.addSeparator(); cm.addDragItem(aitem); } itemlistwnd_addCustomContextMenuCommands(&cm); int r = cm.popAtMouse(); if (r < -10) itemlistwnd_contextMenuResult(r); drags.deleteAll(); filenames.deleteAll(); delete dragitem; return 1; } #if 0 int ItemListWnd::onRightClick(int itemnum, int _x, int _y) { // figure out which column they clicked on int x, l = 0, r = 0; for (int i = 0; i < cols.getNumItems(); i++) { l = r; r += getColumnWidth(i); if (_x >= l && y <= r) break; } if (i >= cols.getNumItems()) return 0; PlayItem *item = convertlParam(itemnum); if (!allowEdition(item, cols[i]->getTag())) return 0; return 0; } #endif void ItemListWnd::metacb_onItemChange(const char *playstring, const char *tag) { int n = getNumItems(); for (int i = 0; i < n; i++) { const char *ps = convertlParam(getItemData(i)); if (ps != NULL && STREQL(ps, playstring)) { onItemChange(i, ps); invalidateItem(i); } } } void ItemListWnd::metacb_onItemDel(const char *playstring) { int n = getNumItems(); for (int i = 0; i < n; i++) { const char *ps = convertlParam(getItemData(i)); if (ps != NULL && STREQL(ps, playstring)) { onItemDel(i, ps); invalidateItem(i); } } }