#include "xdnd.h"
#include "utils.h"
#include "playlist.h"
+#include <cx/string.h>
static void sidebar_class_init(void);
static Boolean sidebar_set_values(Widget old, Widget request, Widget neww, ArgList args, Cardinal *num_args);
static void sidebar_insert_child(Widget child);
Boolean sidebar_acceptfocus(Widget widget, Time *time);
-static void FocusInAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
-static void xdndEnterAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
+static void FocusInAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
+static void SelectElmAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
+static void PopupAP(Widget w, XEvent *event, String *args, Cardinal *nArgs);
static void sidebar_xdnd_callback(Widget w, XtPointer udata, XtPointer cdata);
static XtActionsRec actionslist[] = {
{"focusIn", FocusInAP},
- {"xdnd_enter", xdndEnterAP},
- {"NULL", NULL}
+ {"selectElm", SelectElmAP},
+ {"popup", PopupAP}
};
-static char defaultTranslations[] = "<FocusIn>: focusIn()\n"
- "<Message>XdndEnter: xdnd_enter()\n";
+static char defaultTranslations[] = "<FocusIn>: focusIn()\n"
+ "<Btn1Down>: selectElm()\n"
+ "<Btn3Down>: popup()";
static XtResource constraints[] = {};
static void sidebar_init(Widget request, Widget neww, ArgList args, Cardinal *num_args) {
Sidebar sb = (Sidebar)neww;
- XftColor fg, bg;
+ // initialize everything except XftDraw or other stuff that needs a Window
+
+ XftColor fg, bg, sel2;
fg.color.red = 0;
fg.color.green = 0;
fg.color.blue = 0;
bg.color.blue = 0xFFFF;
bg.color.alpha = 0xFFFF;
+ sel2.color.red = 0xFFFF;
+ sel2.color.green = 0xFFFF;
+ sel2.color.blue = 0;
+ sel2.color.alpha = 0xFFFF;
+
sb->sidebar.fg = fg;
sb->sidebar.bg = bg;
+ sb->sidebar.select2_bg = sel2;
+
+ sb->sidebar.select2 = -1;
sb->sidebar.font = FontFromName(XtDisplay(neww), "Sans:size=11");
if(!sb->sidebar.font) {
fprintf(stderr, "Cannot open font.\nAbort.\n");
exit(-1);
}
+
+ XftFont *xftFont = sb->sidebar.font->fonts->font;
+ int padding = 2;
+ int fontheight = xftFont->ascent;
+ sb->sidebar.elmHeight = fontheight + 2*padding;
}
}
+static int testresize = 1;
static void sidebar_resize(Widget widget) {
+ if(testresize) {
+ XtWidgetGeometry geom;
+ geom.request_mode = CWWidth | CWHeight;
+ geom.width = 200;
+ geom.height = 2000;
+ XtWidgetGeometry result;
+ //XtMakeGeometryRequest(widget, &geom, &result);
+ testresize = 0;
+ }
+ printf("resize\n");
+}
+
+
+static void remove_cb(Widget item, XtPointer index, XtPointer cd) {
+ Widget parent = XtParent(item);
+ Sidebar sb = NULL;
+ XtVaGetValues(parent, XmNuserData, &sb, NULL);
+ int currentTrack = sb->sidebar.window->playlist.current_track;
+ cxListRemove(sb->sidebar.window->playlist.tracks, sb->sidebar.select2);
+ if(sb->sidebar.select2 == currentTrack) {
+ PlayListPlayNext(sb->sidebar.window, true);
+ }
+ sb->sidebar.select2 = -1;
+ SidebarRepaint((Widget)sb);
}
+
static int xdnd_initialized = 0;
static void sidebar_realize(Widget widget, XtValueMask *mask, XSetWindowAttributes *attributes) {
XtWindow(widget),
visual,
widget->core.colormap);
+
+ Dimension w, h;
+
+ Widget parent = XtParent(widget);
+ XtVaSetValues(parent, XmNbackground, WhitePixelOfScreen(XtScreen(parent)), NULL);
+
+ XtMakeResizeRequest(widget, 200, 100, &w, &h);
+
+
+ XmString s1 = XmStringCreateSimple("Remove");
+ sb->sidebar.popupMenu = XmVaCreateSimplePopupMenu(
+ widget, "popup", remove_cb,
+ XmVaPUSHBUTTON, s1, 'R', NULL, NULL,
+ NULL);
+ XtVaSetValues(sb->sidebar.popupMenu, XmNuserData, sb, NULL);
+ XmStringFree(s1);
}
static void sidebar_expose(Widget widget, XEvent *event, Region region) {
- printf("expose\n");
+ //printf("expose\n");
Dimension w, h;
- XtMakeResizeRequest(widget, 200, 200, &w, &h);
+ //XtMakeResizeRequest(widget, 200, 2000, &w, &h);
+
+ w = widget->core.width;
+ h = widget->core.height;
+
+ Widget parent = XtParent(widget);
Sidebar s = (Sidebar)widget;
+ XftFont *xftFont = s->sidebar.font->fonts->font;
+ CxList *tracks = s->sidebar.window->playlist.tracks;
+ size_t numTracks = tracks->size;
+
+ int fontheight = xftFont->ascent;
+ int height = s->sidebar.elmHeight;
- XftDrawRect(s->sidebar.d, &s->sidebar.bg, 0, 0, s->core.width, s->core.height);
- int height = 20;
+ int list_height = numTracks * height;
+ if((list_height > s->core.height) || (w < parent->core.width)) {
+ XtMakeResizeRequest(widget, parent->core.width, list_height + 5, &w, &h);
+ }
+
+
+ XftDrawRect(s->sidebar.d, &s->sidebar.bg, 0, 0, w, h);
+
- printf("current track: %d\n", s->sidebar.window->playlist.current_track);
+ //printf("current track: %d\n", s->sidebar.window->playlist.current_track);
- int i = 0;
- UCX_FOREACH(elm, s->sidebar.window->playlist.tracks) {
- char *name = util_resource_name(elm->data);
+ CxIterator i = cxListIterator(s->sidebar.window->playlist.tracks);
+ cx_foreach(const char *, elm, i) {
+ const char *name = util_resource_name(elm);
XftColor *cg = &s->sidebar.fg;
- if(i == s->sidebar.window->playlist.current_track) {
- XftDrawRect(s->sidebar.d, &s->sidebar.fg, 0, i*height, s->core.width, height);
+ if(i.index == s->sidebar.window->playlist.current_track) {
+ XftDrawRect(s->sidebar.d, &s->sidebar.fg, 0, i.index*height, s->core.width, height);
cg = &s->sidebar.bg;
+ } else if(i.index == s->sidebar.select2) {
+ XftDrawRect(s->sidebar.d, &s->sidebar.select2_bg, 0, i.index*height, s->core.width, height);
}
- XftDrawString8(s->sidebar.d, cg, s->sidebar.font->fonts->font, 10, i*height + 15, (const FcChar8*)name, strlen(name));
-
- i++;
+ XftDrawString8(s->sidebar.d, cg, s->sidebar.font->fonts->font, 10, i.index*height + xftFont->ascent, (const FcChar8*)name, strlen(name));
}
}
static void FocusInAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
- printf("focusin\n");
- fflush(stdout);
+
}
-static void xdndEnterAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
- printf("xdndEnterAP\n");
- fflush(stdout);
+static void SelectElmAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
+ //printf("btn1\n");
+ XButtonEvent *e = &event->xbutton;
+ Sidebar s = (Sidebar)w;
+
+ int selected = e->y / s->sidebar.elmHeight;
+ PlayListPlayTrack(s->sidebar.window, selected);
+ s->sidebar.select2 = -1;
+
+ SidebarRepaint(w);
}
-
-
-
-static void sidebar_xdnd_callback(Widget w, XtPointer udata, XtPointer cdata) {
- printf("xdnd\n");
- fflush(stdout);
+static void PopupAP(Widget w, XEvent *event, String *args, Cardinal *nArgs) {
+ XButtonEvent *e = &event->xbutton;
+ Sidebar s = (Sidebar)w;
- Sidebar s = (Sidebar)cdata;
+ int selected = e->y / s->sidebar.elmHeight;
+ s->sidebar.select2 = selected;
+ SidebarRepaint(w);
+
+ //printf("btn3\n");
+ //fflush(stdout);
- char *urilist = udata;
+ XmMenuPosition(s->sidebar.popupMenu, &event->xbutton);
+ XtManageChild(s->sidebar.popupMenu);
+}
+
+
+static void open_uri(Sidebar s, cxstring uri) {
+ if(uri.length == 0) {
+ return;
+ }
- size_t len = strlen(urilist);
+ const char *urilist = uri.ptr;
+ size_t len = uri.length;
size_t start = 0;
if(len > 7 && !memcmp(urilist, "file://", 7)) {
free(path);
}
+static void sidebar_xdnd_callback(Widget w, XtPointer udata, XtPointer cdata) {
+ printf("xdnd\n");
+ fflush(stdout);
+
+ Sidebar s = (Sidebar)cdata;
+
+ cxstring urllist = cx_str(udata);
+
+ CxStrtokCtx tk = cx_strtok(urllist, cx_str("\r\n"), INT_MAX);
+ cxstring uri;
+ while(cx_strtok_next(&tk, &uri)) {
+ open_uri(s, uri);
+ }
+
+ SidebarRepaint((Widget)s);
+}
+
/* --------------------------- public --------------------------- */
Sidebar sb = (Sidebar)widget;
sb->sidebar.window = win;
}
+
+void SidebarRepaint(Widget widget) {
+ XClearArea(XtDisplay(widget), XtWindow(widget), 0, 0, widget->core.width, widget->core.height, true);
+}