itemlistwnd.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. #include "precomp.h"
  2. #include "itemlistwnd.h"
  3. #include "../../common/metatags.h"
  4. #include "../../studio/api.h"
  5. #include "../skinclr.h"
  6. #include "../../common/filename.h"
  7. #include "../../common/dragitemi.h"
  8. #include "../../common/contextmenu.h"
  9. #define NIFTY_OUTLINE
  10. static SkinColor current("wasabi.itemlist.outline.current");
  11. static SkinColor selborder("wasabi.itemlist.selborder");
  12. static SkinColor focus("wasabi.itemlist.outline.focus");
  13. ItemListColumn_MetaTag::ItemListColumn_MetaTag(const char *newtag, int centered, const char *label)
  14. : ItemListColumn() {
  15. if (label == NULL) label = newtag;
  16. setLabel(label);
  17. tag = newtag;
  18. center = centered;
  19. datatype = api->metadb_getMetaDataType(tag);
  20. }
  21. ItemListColumn_Callback::ItemListColumn_Callback(ItemListWnd *_parent, LPARAM _lparam, const char *name)
  22. : ItemListColumn(name)
  23. {
  24. parent = _parent;
  25. lparam = _lparam;
  26. }
  27. void ItemListColumn_Callback::render(int pos, const char *playstring, Canvas &c, RECT &r) {
  28. parent->userRender(pos, playstring, c, r, lparam);
  29. }
  30. void ItemListColumn_Callback::columnToText(int pos, const char *playstring, char *str, int maxlen) {
  31. parent->userColumnToText(pos, playstring, lparam, str, maxlen);
  32. }
  33. void ItemListColumn_MetaTag::render(int pos, const char *playstring, Canvas &canvas, RECT &r) {
  34. char buf[4096]="";
  35. if (api->metadb_getMetaData(playstring, tag, buf, 4096) <= 1) return;
  36. api->metadb_renderData(&canvas, r, buf, datatype, center);
  37. }
  38. void ItemListColumn_MetaTag::columnToText(int pos, const char *playstring, char *str, int maxlen) {
  39. api->metadb_getMetaData(playstring, tag, str, maxlen);
  40. }
  41. const char *ItemListColumn_MetaTag::getTag() {
  42. return tag;
  43. }
  44. void ItemListColumn_Numbered::render(int pos, const char *playstring, Canvas &c, RECT &r) {
  45. StringPrintf buf("%d.", pos+1);
  46. c.textOutEllipsed(r.left, r.top, r.right - r.left, r.bottom-r.top, buf);
  47. }
  48. void ItemListColumn_Numbered::columnToText(int pos, const char *playstring, char *str, int maxlen) {
  49. StringPrintf buf("%d", pos+1);
  50. STRNCPY(str, buf, maxlen);
  51. }
  52. ItemListWnd::ItemListWnd() {
  53. keep = NULL;
  54. item_invalidate_border++;
  55. }
  56. ItemListWnd::~ItemListWnd() {
  57. api->syscb_deregisterCallback(static_cast<MetaCallbackI *>(this));
  58. }
  59. int ItemListWnd::onInit() {
  60. ITEMLISTWND_PARENT::onInit();
  61. api->syscb_registerCallback(static_cast<MetaCallbackI *>(this));
  62. return 1;
  63. }
  64. int ItemListWnd::insertColumn(ItemListColumn *column, int width, int pos) {
  65. column->setWidth(width);
  66. return ITEMLISTWND_PARENT::insertColumn(column, pos);
  67. }
  68. int ItemListWnd::onBeginDrag(int iItem) {
  69. if (!wantAutoDrag()) return ITEMLISTWND_PARENT::onBeginDrag(iItem);
  70. // add all the entries
  71. int n, i, c = 0;
  72. n = getNumItems();
  73. if (n == 0) return 0; // empty list
  74. ASSERT(keep == NULL);
  75. keep = new PtrList<FilenameNC>();
  76. // count up the items
  77. for (i = 0; i < n; i++) {
  78. if (getItemSelected(i)) { // expose all the pointers we can
  79. LPARAM lparam = getItemData(i);
  80. if (!addMoreDragTypes(i)) {
  81. FilenameNC *fn = keep->addItem(new FilenameNC(convertlParam(lparam)));
  82. addDragItem(DD_FILENAME, static_cast<Filename*>(fn));
  83. }
  84. c++;
  85. }
  86. }
  87. if (keep->getNumItems() == 0 || c <= 0) {
  88. delete keep; keep = NULL;
  89. return 0;
  90. }
  91. handleDrag();
  92. return 1;
  93. }
  94. int ItemListWnd::dragComplete(int success) {
  95. ASSERT(keep != NULL);
  96. keep->deleteAll();
  97. delete keep; keep = NULL;
  98. return 1;
  99. }
  100. int ItemListWnd::ownerDraw(Canvas *canvas, int pos, RECT *r, LPARAM lParam, int isselected, int isfocused) {
  101. const char *playstring = convertlParam(lParam);
  102. if (playstring == NULL) return 0;
  103. COLORREF bgcolor = isfocused ? getFocusColor(lParam) : getSelBgColor(lParam);
  104. COLORREF fgcolor = getTextColor(lParam);
  105. int iscur = getSelected(lParam);
  106. RECT box;
  107. canvas->getClipBox(&box);
  108. if (!getBgBitmap()) {
  109. RECT r2 = *r;
  110. r2.left = box.left;
  111. RegionI *reg = new RegionI(&r2);
  112. canvas->selectClipRgn(reg);
  113. delete reg;
  114. canvas->fillRect(r, getBgColor());
  115. }
  116. canvas->setTextColor(fgcolor);
  117. // ASSERT(cols.getNumItems() == getNumColumns());
  118. if (isselected) {
  119. RECT mr = *r;
  120. canvas->fillRect(&mr, bgcolor);
  121. /*au gratin potatoes/broccoli
  122. chicken^2
  123. salad, croutons, cheese, ranch
  124. fries */
  125. #ifdef NIFTY_OUTLINE
  126. int prevsel = getItemSelected(pos-1);
  127. int nextsel = getItemSelected(pos+1);
  128. mr.bottom--;
  129. canvas->pushPen(selborder);
  130. canvas->lineDraw(mr.left, mr.top, mr.left, mr.bottom);
  131. canvas->lineDraw(mr.right-1, mr.top, mr.right-1, mr.bottom);
  132. if (!prevsel) canvas->lineDraw(mr.left, mr.top, mr.right, mr.top);
  133. if (!nextsel) canvas->lineDraw(mr.left, mr.bottom, mr.right, mr.bottom);
  134. canvas->popPen();
  135. #endif
  136. }
  137. if (isfocused || iscur) {
  138. int pentype = isfocused ? FALSE : TRUE;
  139. int boxcolor = iscur ? current : focus;
  140. canvas->drawRect(r, pentype, boxcolor);
  141. }
  142. canvas->pushTextSize(getFontSize());
  143. int x = 1+r->left;
  144. for (int i = 0; i < getNumColumns(); i++) {
  145. ItemListColumn *col = (ItemListColumn *)enumListColumn(i);
  146. RECT ir;
  147. ir.left = x;
  148. ir.right = x + getColumnWidth(i);
  149. ir.top = r->top;
  150. ir.bottom = r->bottom;
  151. if (ir.right >= box.left && ir.bottom >= box.top && ir.left <= box.right && ir.top <= box.bottom) {
  152. col->render(pos, playstring, *canvas, ir);
  153. }
  154. x = ir.right;
  155. }
  156. canvas->popTextSize();
  157. return 1;
  158. }
  159. void ItemListWnd::convertlParamColumn(int col, int pos, LPARAM param, char *str, int maxlen) {
  160. ASSERT(str != NULL);
  161. ItemListColumn *cl = (ItemListColumn *)enumListColumn(col);
  162. const char *playstring = convertlParam(param);
  163. cl->columnToText(pos, playstring, str, maxlen);
  164. }
  165. int ItemListWnd::onContextMenu(int x, int y) {
  166. PtrList<FilenameNC> filenames;
  167. DragItemI *dragitem = NULL;
  168. if ((dragitem = itemlistwnd_getDragItem(x, y)) == NULL) {
  169. DragItemT<Filename> *di = new DragItemT<Filename>;
  170. int n = getNumItems();
  171. for (int i = 0; i < n; i++) {
  172. if (getItemSelected(i)) {
  173. LPARAM lparam = getItemData(i);
  174. const char *playstring = convertlParam(lparam);
  175. di->addDatum(filenames.addItem(new FilenameNC(playstring)));
  176. }
  177. }
  178. dragitem = di;
  179. }
  180. ContextMenu cm(this, filenames.getNumItems() ? dragitem : NULL, false);
  181. PtrList<DragItemI> drags;
  182. for (int i = 0; ; i++) {
  183. DragItemI *aitem = itemlistwnd_getSecondDragItem(i);
  184. if (aitem == NULL) break;
  185. drags.addItem(aitem);
  186. if (cm.getNumCommands()) cm.addSeparator();
  187. cm.addDragItem(aitem);
  188. }
  189. itemlistwnd_addCustomContextMenuCommands(&cm);
  190. int r = cm.popAtMouse();
  191. if (r < -10) itemlistwnd_contextMenuResult(r);
  192. drags.deleteAll();
  193. filenames.deleteAll();
  194. delete dragitem;
  195. return 1;
  196. }
  197. #if 0
  198. int ItemListWnd::onRightClick(int itemnum, int _x, int _y) {
  199. // figure out which column they clicked on
  200. int x, l = 0, r = 0;
  201. for (int i = 0; i < cols.getNumItems(); i++) {
  202. l = r;
  203. r += getColumnWidth(i);
  204. if (_x >= l && y <= r) break;
  205. }
  206. if (i >= cols.getNumItems()) return 0;
  207. PlayItem *item = convertlParam(itemnum);
  208. if (!allowEdition(item, cols[i]->getTag())) return 0;
  209. return 0;
  210. }
  211. #endif
  212. void ItemListWnd::metacb_onItemChange(const char *playstring, const char *tag) {
  213. int n = getNumItems();
  214. for (int i = 0; i < n; i++) {
  215. const char *ps = convertlParam(getItemData(i));
  216. if (ps != NULL && STREQL(ps, playstring)) {
  217. onItemChange(i, ps);
  218. invalidateItem(i);
  219. }
  220. }
  221. }
  222. void ItemListWnd::metacb_onItemDel(const char *playstring) {
  223. int n = getNumItems();
  224. for (int i = 0; i < n; i++) {
  225. const char *ps = convertlParam(getItemData(i));
  226. if (ps != NULL && STREQL(ps, playstring)) {
  227. onItemDel(i, ps);
  228. invalidateItem(i);
  229. }
  230. }
  231. }