+2005-04-03 mallum,,, <mallum@openedhand.com>
+
+ * Makefile:
+ * cltr-core.c:
+ * cltr-core.h:
+ * cltr-events.c:
+ * cltr-events.h:
+ * cltr-photo-grid.c: (cltr_photo_grid_handle_xkeyevent),
+ (cltr_photo_grid_handle_xevent), (cltr_photo_grid_cell_new),
+ (cltr_photo_grid_append_cell), (ctrl_photo_grid_cell_to_coords),
+ (ctrl_photo_grid_get_zoomed_coords), (cell_is_offscreen),
+ (cltr_photo_grid_idle_cb), (cltr_photo_grid_navigate),
+ (cltr_photo_grid_activate_cell), (cltr_photo_grid_populate),
+ (cltr_photo_grid_paint), (cltr_photo_grid_show),
+ (cltr_photo_grid_new):
+ * cltr-photo-grid.h:
+ * cltr-private.h:
+ * cltr-texture.c:
+ * cltr-texture.h:
+ * cltr-widget.c:
+ * cltr-widget.h:
+ * cltr-window.c:
+ * cltr-window.h:
+ * cltr.c:
+ * cltr.h:
+ Add very basic initial toolkit infrastructure
+
2005-03-31 mallum,,, <mallum@openedhand.com>
* cltr-photo-grid.c: (cltr_photo_grid_append_cell),
.c.o:
$(CC) -g -Wall $(CFLAGS) $(INCS) -c $*.c
-OBJS=cltr.o pixbuf.o util.o fonts.o cltr-photo-grid.o cltr-texture.o
+OBJS=cltr.o pixbuf.o util.o fonts.o \
+ cltr-core.o \
+ cltr-texture.o \
+ cltr-widget.o \
+ cltr-events.o \
+ cltr-window.o \
+ cltr-photo-grid.o
+
+# cltr-photo-grid.o
clutter: $(OBJS)
$(CC) -g -Wall -o $@ $(OBJS) $(LIBS)
-$(OBJS): pixbuf.h util.h fonts.h cltr.h cltr-photo-grid.h cltr-texture.h
+$(OBJS): pixbuf.h util.h fonts.h \
+ cltr.h \
+ cltr-private.h \
+ cltr-events.h \
+ cltr-texture.h \
+ cltr-widget.h \
+ cltr-window.h \
+ cltr-photo-grid.h
+
+#cltr-photo-grid.h
+
clean:
rm -fr *.o clutter test
--- /dev/null
+#include "cltr-core.h"
+#include "cltr-private.h"
+
+int
+cltr_init(int *argc, char ***argv)
+{
+ int gl_attributes[] =
+ {
+ GLX_RGBA,
+ GLX_DOUBLEBUFFER,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ 0
+ };
+
+ XVisualInfo *vinfo;
+
+
+ g_thread_init (NULL);
+ // XInitThreads ();
+
+ if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
+ {
+ return 0;
+ }
+
+ CltrCntx.xscreen = DefaultScreen(CltrCntx.xdpy);
+ CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
+
+ if ((vinfo = glXChooseVisual(CltrCntx.xdpy,
+ CltrCntx.xscreen,
+ gl_attributes)) == NULL)
+ {
+ fprintf(stderr, "Unable to find visual\n");
+ return 0;
+ }
+
+ CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True);
+
+ cltr_events_init();
+
+ return 1;
+}
--- /dev/null
+#ifndef _HAVE_CLTR_CORE_H
+#define _HAVE_CLTR_CORE_H
+
+#include "cltr.h"
+
+int
+cltr_init(int *argc, char ***argv);
+
+#endif
--- /dev/null
+#include <X11/keysym.h>
+
+#include "cltr-events.h"
+#include "cltr-private.h"
+
+typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data);
+
+typedef struct
+{
+ GSource source;
+ Display *display;
+ GPollFD event_poll_fd;
+}
+CltrXEventSource;
+
+static gboolean
+x_event_prepare (GSource *source,
+ gint *timeout)
+{
+ Display *display = ((CltrXEventSource*)source)->display;
+
+ *timeout = -1;
+
+ return XPending (display);
+}
+
+static gboolean
+x_event_check (GSource *source)
+{
+ CltrXEventSource *display_source = (CltrXEventSource*)source;
+ gboolean retval;
+
+ if (display_source->event_poll_fd.revents & G_IO_IN)
+ retval = XPending (display_source->display);
+ else
+ retval = FALSE;
+
+ return retval;
+}
+
+static gboolean
+x_event_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ Display *display = ((CltrXEventSource*)source)->display;
+ CltrXEventFunc event_func = (CltrXEventFunc) callback;
+
+ XEvent xev;
+
+ if (XPending (display))
+ {
+ XNextEvent (display, &xev);
+
+ if (event_func)
+ (*event_func) (&xev, user_data);
+ }
+
+ return TRUE;
+}
+
+static const GSourceFuncs x_event_funcs = {
+ x_event_prepare,
+ x_event_check,
+ x_event_dispatch,
+ NULL
+};
+
+void
+cltr_dispatch_expose(XExposeEvent *xexpev)
+{
+ // cltr_photo_grid_redraw(Grid);
+}
+
+void
+cltr_dispatch_x_event (XEvent *xevent,
+ gpointer data)
+{
+ /* Should actually forward on to focussed widget */
+
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+
+ cltr_widget_handle_xevent(ctx->window, xevent);
+
+#if 0
+ switch (xevent->type)
+ {
+ case MapNotify:
+ CLTR_DBG("Map Notify Event");
+ break;
+ case Expose:
+ CLTR_DBG("Expose"); /* TODO COMPRESS */
+ cltr_dispatch_expose(&xevent->xexpose);
+ break;
+ case KeyPress:
+ CLTR_DBG("KeyPress");
+ cltr_dispatch_keypress(&xevent->xkey);
+ break;
+ }
+#endif
+}
+
+void
+cltr_events_init()
+{
+ GMainContext *gmain_context;
+ int connection_number;
+ GSource *source;
+ CltrXEventSource *display_source;
+
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+
+ /* g_main loop stuff */
+
+ gmain_context = g_main_context_default ();
+
+ g_main_context_ref (gmain_context);
+
+ connection_number = ConnectionNumber (CltrCntx.xdpy);
+
+ source = g_source_new ((GSourceFuncs *)&x_event_funcs,
+ sizeof (CltrXEventSource));
+
+ display_source = (CltrXEventSource *)source;
+
+ display_source->event_poll_fd.fd = connection_number;
+ display_source->event_poll_fd.events = G_IO_IN;
+ display_source->display = CltrCntx.xdpy;
+
+ g_source_add_poll (source, &display_source->event_poll_fd);
+ g_source_set_can_recurse (source, TRUE);
+
+ g_source_set_callback (source,
+ (GSourceFunc) cltr_dispatch_x_event,
+ NULL /* no userdata */, NULL);
+
+ g_source_attach (source, gmain_context);
+ g_source_unref (source);
+
+ ctx->internal_event_q = g_queue_new();
+}
+
+void
+cltr_main_loop()
+{
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+
+ /*
+ GMainLoop *loop;
+
+ loop = g_main_loop_new (g_main_context_default (), FALSE);
+
+ g_main_loop_run (loop);
+ */
+
+ while (TRUE)
+ {
+ if (!g_queue_is_empty (ctx->internal_event_q))
+ {
+ CltrWidget *widget = NULL;
+ CltrWindow *win = CLTR_WINDOW(ctx->window);
+
+ while ((widget = g_queue_pop_head(ctx->internal_event_q)) != NULL)
+ {
+ cltr_widget_paint(widget);
+ }
+
+ /* Swap Buffers */
+ glXSwapBuffers(ctx->xdpy, cltr_window_xwin(win));
+ }
+
+ /* while (g_main_context_pending(g_main_context_default ())) */
+ g_main_context_iteration (g_main_context_default (), TRUE);
+
+ }
+}
--- /dev/null
+#ifndef _HAVE_CLTR_EVENT_H
+#define _HAVE_CLTR_EVENT_H
+
+#include "cltr.h"
+
+
+
+void
+cltr_main_loop();
+
+void
+cltr_dispatch_x_event (XEvent *xevent,
+ gpointer data);
+
+void
+cltr_events_init();
+
+#endif
#include "cltr-photo-grid.h"
+#include "cltr-private.h"
+
+/*
+ TODO
+
+ - image cache !!
+
+ - change idle_cb to timeouts, reduce tearing + inc interactivity on
+ image load
+
+ - Split events into seperate file ( break up ctrl.c )
+
+ - offset zoom a little to give border around picture grid
+
+ - figure out highlighting selected cell
+
+ - tape on pictures ?
+
+ - tidy this code here + document !
+ - fix threads, lower priority ?
+
+ */
+
+#define ANIM_FPS 60
+#define FPS_TO_TIMEOUT(t) (1000/(t))
+
+struct CltrPhotoGridCell
+{
+ Pixbuf *pixb;
+ float angle;
+ CltrTexture *texture;
+ gint anim_step;
+
+ CltrPhotoGridCellState state;
+};
+
+struct CltrPhotoGrid
+{
+ CltrWidget widget;
+
+ gchar *img_path;
+
+ int n_rows;
+ int n_cols;
+ int row_offset; /* for scrolling */
+
+ int cell_width;
+ int cell_height;
+
+ GList *cells_tail;
+ GList *cell_active;
+
+ /* animation / zoom etc stuff */
+
+ int anim_n_steps, anim_step;
+
+ float zoom_min, zoom_max, zoom_step;
+
+ float view_min_x, view_max_x, view_min_y, view_max_y;
+
+ float scroll_dist;
+
+ CltrPhotoGridState state;
+
+ int scroll_state, scroll_step; /* urg */
+
+};
+
+static void
+cltr_photo_grid_paint(CltrWidget *widget);
+
+static gboolean
+cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_photo_grid_show(CltrWidget *widget);
+
/* this likely shouldn'y go here */
static GMutex *Mutex_GRID = NULL;
-ClutterPhotoGridCell*
-cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
- Pixbuf *pixb,
- const gchar *filename)
+
+static void
+cltr_photo_grid_handle_xkeyevent(CltrPhotoGrid *grid, XKeyEvent *xkeyev)
{
- ClutterPhotoGridCell *cell = NULL;
- int maxw = grid->width, maxh = grid->height;
+ KeySym kc;
+
+ kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
+
+ switch (kc)
+ {
+ case XK_Left:
+ case XK_KP_Left:
+ cltr_photo_grid_navigate(grid, CLTR_WEST);
+ break;
+ case XK_Up:
+ case XK_KP_Up:
+ cltr_photo_grid_navigate(grid, CLTR_NORTH);
+ break;
+ case XK_Right:
+ case XK_KP_Right:
+ cltr_photo_grid_navigate(grid, CLTR_EAST);
+ break;
+ case XK_Down:
+ case XK_KP_Down:
+ cltr_photo_grid_navigate(grid, CLTR_SOUTH);
+ break;
+ case XK_Return:
+ cltr_photo_grid_activate_cell(grid);
+ break;
+ default:
+ CLTR_DBG("unhandled keysym");
+ }
+}
+
+static gboolean
+cltr_photo_grid_handle_xevent (CltrWidget *widget, XEvent *xev)
+{
+ CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget);
+
+ switch (xev->type)
+ {
+ case KeyPress:
+ CLTR_DBG("KeyPress");
+ cltr_photo_grid_handle_xkeyevent(grid, &xev->xkey);
+ break;
+ }
+
+ return TRUE;
+}
+
+
+CltrPhotoGridCell*
+cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
+ Pixbuf *pixb,
+ const gchar *filename)
+{
+ CltrPhotoGridCell *cell = NULL;
+ int maxw = grid->widget.width, maxh = grid->widget.height;
int neww = 0, newh = 0;
- cell = g_malloc0(sizeof(ClutterPhotoGridCell));
+ cell = g_malloc0(sizeof(CltrPhotoGridCell));
if (pixb->width > pixb->height) /* landscape */
{
}
void
-cltr_photo_grid_append_cell(ClutterPhotoGrid *grid,
- ClutterPhotoGridCell *cell)
+cltr_photo_grid_append_cell(CltrPhotoGrid *grid,
+ CltrPhotoGridCell *cell)
{
grid->cells_tail = g_list_append(grid->cells_tail, cell);
/* relative */
static void
-ctrl_photo_grid_cell_to_coords(ClutterPhotoGrid *grid,
+ctrl_photo_grid_cell_to_coords(CltrPhotoGrid *grid,
GList *cell,
int *x,
int *y)
}
static void
-ctrl_photo_grid_get_zoomed_coords(ClutterPhotoGrid *grid,
+ctrl_photo_grid_get_zoomed_coords(CltrPhotoGrid *grid,
int x,
int y,
float *tx,
}
static gboolean
-cell_is_offscreen(ClutterPhotoGrid *grid,
+cell_is_offscreen(CltrPhotoGrid *grid,
GList *cell,
CltrDirection *where)
{
gboolean
cltr_photo_grid_idle_cb(gpointer data)
{
- ClutterPhotoGrid *grid = (ClutterPhotoGrid *)data;
+ CltrPhotoGrid *grid = (CltrPhotoGrid *)data;
- cltr_photo_grid_redraw(grid);
+ cltr_widget_queue_paint(CLTR_WIDGET(grid));
switch(grid->state)
{
void
-cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
+cltr_photo_grid_navigate(CltrPhotoGrid *grid,
CltrDirection direction)
{
GList *cell_orig = grid->cell_active;
}
if (grid->state != CLTR_PHOTO_GRID_STATE_ZOOMED)
- g_idle_add(cltr_photo_grid_idle_cb, grid);
+ g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
+ cltr_photo_grid_idle_cb, grid);
}
if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
grid->anim_step = 0;
zoom = grid->zoom_max;
- g_idle_add(cltr_photo_grid_idle_cb, grid);
+ g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
+ cltr_photo_grid_idle_cb, grid);
}
ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
CLTR_DBG("x: %f, y: %f", grid->view_max_x , grid->view_max_y);
- cltr_photo_grid_redraw(grid);
+ cltr_widget_queue_paint(CLTR_WIDGET(grid));
}
}
void /* bleh badly named */
-cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid)
+cltr_photo_grid_activate_cell(CltrPhotoGrid *grid)
{
if (grid->state == CLTR_PHOTO_GRID_STATE_BROWSE)
{
grid->state = CLTR_PHOTO_GRID_STATE_ZOOM_IN;
- g_idle_add(cltr_photo_grid_idle_cb, grid);
+ g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
+ cltr_photo_grid_idle_cb, grid);
}
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED)
{
grid->view_min_x = 0.0;
grid->view_min_y = 0.0; /*- (grid->row_offset * grid->cell_height);*/
- g_idle_add(cltr_photo_grid_idle_cb, grid);
+ g_timeout_add(FPS_TO_TIMEOUT(ANIM_FPS),
+ cltr_photo_grid_idle_cb, grid);
}
/* que a draw ? */
gpointer
cltr_photo_grid_populate(gpointer data)
{
- ClutterPhotoGrid *grid = (ClutterPhotoGrid *)data;
+ CltrPhotoGrid *grid = (CltrPhotoGrid *)data;
GDir *dir;
GError *error;
const gchar *entry = NULL;
if (pixb)
{
- ClutterPhotoGridCell *cell;
+ CltrPhotoGridCell *cell;
gchar buf[24];
cell = cltr_photo_grid_cell_new(grid, pixb, entry);
g_mutex_unlock(Mutex_GRID);
- cltr_photo_grid_redraw(grid);
+ cltr_widget_queue_paint(CLTR_WIDGET(grid));
return NULL;
}
-void
-cltr_photo_grid_redraw(ClutterPhotoGrid *grid)
+static void
+cltr_photo_grid_paint(CltrWidget *widget)
{
- int x = 0, y = 0, rows = grid->n_rows+1, cols = 0, i =0;
+ int x = 0, y = 0, rows = 0, cols = 0, i =0;
GList *cell_item;
float zoom, trans_x, trans_y;
+ CltrWindow *win = CLTR_WINDOW(widget->parent);
+
+ CltrPhotoGrid *grid = (CltrPhotoGrid *)widget;
+
+ rows = grid->n_rows+1;
/* CLTR_MARK();*/
if (grid->cells_tail == NULL)
{
/* No pictures to paint yet */
+ CltrWindow *win = CLTR_WINDOW(grid->widget.parent);
+
glColor3f(0.6, 0.6, 0.62);
- glRecti(0, 0, 640, 480);
+ glRecti(0, 0, widget->width, widget->height);
glPopMatrix();
- glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);
return;
}
trans_y = ((grid->view_max_y - grid->view_min_y + scroll_min_y_offset) * f) ;
y = 0;
- printf("%f,%f, %f\n", grid->view_max_y, grid->view_min_y, scroll_min_y_offset);
-
}
}
else if (grid->state == CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE)
grid->anim_step++;
- if (grid->anim_step >= grid->anim_n_steps)
+ if (grid->anim_step >= (grid->anim_n_steps/4))
{
grid->state = CLTR_PHOTO_GRID_STATE_BROWSE;
grid->anim_step = 0;
+ zoom = grid->zoom_min;
}
else
{
- float f = (float)grid->anim_step / grid->anim_n_steps;
+ float f = (float)grid->anim_step / (grid->anim_n_steps/4);
trans_y += (grid->scroll_dist * f);
if (grid->scroll_dist > 0) /* up */
{
y = (grid->row_offset-1) * grid->cell_height;
- /* cell_item = g_list_nth(grid->cells_tail, grid->n_cols * (grid->row_offset+1));*/
}
else /* down */
{
x = 0;
while (cols--)
{
- ClutterPhotoGridCell *cell = (ClutterPhotoGridCell *)cell_item->data;
+ CltrPhotoGridCell *cell = (CltrPhotoGridCell *)cell_item->data;
Pixbuf *pixb = NULL;
int x1, x2, y1, y2, thumb_w, thumb_h;
int ns_border, ew_border;
/* finally paint background */
glDisable(GL_TEXTURE_2D);
glColor3f(0.6, 0.6, 0.62);
- glRecti(0, 0, 640, 480);
-
- glXSwapBuffers(CltrCntx.xdpy, grid->parent->xwin);
+ glRecti(0, 0, widget->width, widget->height);
g_mutex_lock(Mutex_GRID);
}
-ClutterPhotoGrid*
-cltr_photo_grid_new(ClutterWindow *win,
+static void
+cltr_photo_grid_show(CltrWidget *widget)
+{
+ CltrPhotoGrid* grid = CLTR_PHOTO_GRID(widget);
+
+ cltr_widget_queue_paint(widget);
+}
+
+CltrWidget*
+cltr_photo_grid_new(int width,
+ int height,
int n_cols,
int n_rows,
const gchar *img_path)
{
- ClutterPhotoGrid *grid = NULL;
+ CltrPhotoGrid *grid = NULL;
GThread *loader_thread;
- grid = util_malloc0(sizeof(ClutterPhotoGrid));
+ grid = g_malloc0(sizeof(CltrPhotoGrid));
- grid->img_path = strdup(img_path);
+ grid->widget.width = width;
+ grid->widget.height = height;
+
+ grid->widget.show = cltr_photo_grid_show;
+ grid->widget.paint = cltr_photo_grid_paint;
+
+ grid->widget.xevent_handler = cltr_photo_grid_handle_xevent;
- grid->width = win->width;
- grid->height = win->height;
+ grid->img_path = strdup(img_path);
grid->n_cols = n_cols;
grid->n_rows = n_rows;
- grid->parent = win;
- grid->cell_width = grid->width / n_cols;
- grid->cell_height = grid->height / n_rows;
+ grid->cell_width = grid->widget.width / n_cols;
+ grid->cell_height = grid->widget.height / n_rows;
grid->state = CLTR_PHOTO_GRID_STATE_LOADING;
- grid->anim_n_steps = 40; /* value needs to be calced dep on rows */
+ grid->anim_n_steps = 20; /* value needs to be calced dep on rows */
grid->anim_step = 0;
- /*
- grid->zoom_step = 0.05;
- grid->zoom = 1.0;
- */
grid->zoom_min = 1.0;
- grid->view_min_x = (grid->width - (grid->zoom_min * grid->width))/2.0;
+ grid->view_min_x = (grid->widget.width - (grid->zoom_min * grid->widget.width))/2.0;
grid->view_min_y = 0.0;
-
/* Assmes cols == rows */
grid->zoom_max = /* 1.0 + */ (float) (n_rows * 1.0); // - 0.3;
TRUE,
NULL);
- /*
- ctrl_photo_grid_cell_to_coords(grid, grid->cell_active, &x, &y);
-
-
- ctrl_photo_grid_get_zoomed_coords(grid, grid->zoom_max,
- x, y,
- &grid->view_max_x,
- &grid->view_max_y);
- */
-
- g_idle_add(cltr_photo_grid_idle_cb, grid);
+ g_timeout_add(FPS_TO_TIMEOUT(20),
+ cltr_photo_grid_idle_cb, grid);
- return grid;
+ return CLTR_WIDGET(grid);
}
#include "cltr.h"
-typedef struct ClutterPhotoGrid ClutterPhotoGrid;
+typedef struct CltrPhotoGrid CltrPhotoGrid;
-typedef struct ClutterPhotoGridCell ClutterPhotoGridCell;
+typedef struct CltrPhotoGridCell CltrPhotoGridCell;
-typedef enum ClutterPhotoGridState
+#define CLTR_PHOTO_GRID(w) (CltrPhotoGrid*)(w)
+
+typedef enum CltrPhotoGridState
{
CLTR_PHOTO_GRID_STATE_LOADING ,
CLTR_PHOTO_GRID_STATE_LOAD_COMPLETE ,
CLTR_PHOTO_GRID_STATE_ZOOMED_MOVE ,
CLTR_PHOTO_GRID_STATE_SCROLLED_MOVE ,
}
-ClutterPhotoGridState;
+CltrPhotoGridState;
-typedef enum ClutterPhotoGridCellState
+typedef enum CltrPhotoGridCellState
{
CLTR_PHOTO_GRID_CELL_STATE_APPEARING,
CLTR_PHOTO_GRID_CELL_STATE_STATIC,
}
-ClutterPhotoGridCellState;
-
-
-struct ClutterPhotoGridCell
-{
- Pixbuf *pixb;
- float angle;
- CltrTexture *texture;
- gint anim_step;
-
- ClutterPhotoGridCellState state;
-};
-
-struct ClutterPhotoGrid
-{
- /* XXX should be base widget stuff */
- int x,y;
- int width;
- int height;
- ClutterWindow *parent;
-
- /* ****** */
-
- gchar *img_path;
-
- int n_rows;
- int n_cols;
- int row_offset; /* for scrolling */
+CltrPhotoGridCellState;
- int cell_width;
- int cell_height;
- GList *cells_tail;
- GList *cell_active;
-
- /* animation / zoom etc stuff */
-
- int anim_n_steps, anim_step;
-
- float zoom_min, zoom_max, zoom_step;
-
- float view_min_x, view_max_x, view_min_y, view_max_y;
-
- float scroll_dist;
-
- ClutterPhotoGridState state;
-
- int scroll_state, scroll_step; /* urg */
-
-};
-
-ClutterPhotoGridCell*
-cltr_photo_grid_cell_new(ClutterPhotoGrid *grid,
+CltrPhotoGridCell*
+cltr_photo_grid_cell_new(CltrPhotoGrid *grid,
Pixbuf *pixb,
const gchar *filename);
void
-cltr_photo_grid_append_cell(ClutterPhotoGrid *grid,
- ClutterPhotoGridCell *cell);
+cltr_photo_grid_append_cell(CltrPhotoGrid *grid,
+ CltrPhotoGridCell *cell);
void
-cltr_photo_grid_navigate(ClutterPhotoGrid *grid,
+cltr_photo_grid_navigate(CltrPhotoGrid *grid,
CltrDirection direction) ;
void /* bleh badly named */
-cltr_photo_grid_activate_cell(ClutterPhotoGrid *grid);
+cltr_photo_grid_activate_cell(CltrPhotoGrid *grid);
gpointer
cltr_photo_grid_populate(gpointer data) ;
void
-cltr_photo_grid_redraw(ClutterPhotoGrid *grid);
+cltr_photo_grid_redraw(CltrPhotoGrid *grid);
-ClutterPhotoGrid*
-cltr_photo_grid_new(ClutterWindow *win,
+CltrWidget*
+cltr_photo_grid_new(int width,
+ int height,
int n_cols,
int n_rows,
- const gchar *imgs_path);
+ const gchar *img_path);
+
#endif
--- /dev/null
+#ifndef _HAVE_CLTR_PRIVATE_H
+#define _HAVE_CLTR_PRIVATE_H
+
+#include "cltr.h"
+
+#define CLTR_WANT_DEBUG 1
+
+#if (CLTR_WANT_DEBUG)
+
+#define CLTR_DBG(x, a...) \
+ g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
+
+#define CLTR_GLERR() \
+ { \
+ GLenum err = glGetError (); /* Roundtrip */ \
+ if (err != GL_NO_ERROR) \
+ { \
+ g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n", \
+ err, __func__, __LINE__); \
+ } \
+ }
+
+#else
+
+#define CLTR_DBG(x, a...) do {} while (0)
+#define CLTR_GLERR() do {} while (0)
+
+#endif
+
+#define CLTR_MARK() CLTR_DBG("mark")
+
+typedef void (*WidgetPaintMethod) (CltrWidget *widget ) ;
+typedef void (*WidgetShowMethod) (CltrWidget *widget ) ;
+typedef void (*WidgetDestroyMethod) (CltrWidget *widget) ;
+
+typedef gboolean (*WidgetXEventHandler) (CltrWidget *widget, XEvent *xev) ;
+
+struct CltrWidget
+{
+ int x,y,width,height;
+ CltrWidget *parent;
+
+ gboolean visible;
+
+ GList *children;
+
+ /* methods */
+
+ WidgetPaintMethod paint;
+ WidgetShowMethod show;
+ WidgetDestroyMethod destroy;
+
+ WidgetXEventHandler xevent_handler;
+};
+
+typedef struct ClutterMainContext ClutterMainContext;
+
+struct ClutterMainContext
+{
+ Display *xdpy;
+ Window xwin_root;
+ int xscreen;
+ GC xgc;
+
+ GLXContext gl_context;
+
+ CltrWidget *window;
+ GQueue *internal_event_q;
+};
+
+ClutterMainContext CltrCntx;
+
+#define CLTR_CONTEXT() &CltrCntx
+
+#endif
#include "cltr-texture.h"
+#include "cltr-private.h"
/*
IDEAS or less memory
#include "cltr.h"
+typedef struct CltrTexture CltrTexture;
+
+struct CltrTexture
+{
+ Pixbuf *pixb;
+
+ int width, height;
+
+ int n_x_tiles, n_y_tiles;
+ int *tile_x_position, *tile_x_size, *tile_x_waste;
+ int *tile_y_position, *tile_y_size, *tile_y_waste;
+
+ GLuint *tiles;
+
+ gint refcnt;
+};
+
+
CltrTexture*
cltr_texture_new(Pixbuf *pixb);
--- /dev/null
+#include "cltr-widget.h"
+#include "cltr-private.h"
+
+CltrWidget*
+cltr_widget_new(void)
+{
+ CltrWidget *w = NULL;
+
+ w = g_malloc0(sizeof(CltrWidget));
+
+ return w;
+}
+
+void
+cltr_widget_show(CltrWidget *widget)
+{
+ if (widget->show)
+ {
+ widget->visible = TRUE;
+ widget->show(widget);
+ }
+}
+
+void
+cltr_widget_show_all(CltrWidget *widget)
+{
+ GList *widget_item = widget->children;;
+
+ if (widget_item)
+ {
+ do
+ {
+ CltrWidget *child = CLTR_WIDGET(widget_item->data);
+
+ cltr_widget_show(child);
+ }
+ while ((widget_item = g_list_next(widget_item)) != NULL);
+ }
+
+ cltr_widget_show(widget);
+}
+
+void
+cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y)
+{
+ widget->children = g_list_append(widget->children, child);
+
+ child->parent = widget;
+ child->x = x;
+ child->y = y;
+}
+
+
+void
+cltr_widget_hide(CltrWidget *widget)
+{
+ widget->visible = FALSE;
+}
+
+void
+cltr_widget_paint(CltrWidget *widget)
+{
+ if (widget->paint && widget->visible)
+ widget->paint(widget);
+}
+
+void
+cltr_widget_queue_paint(CltrWidget *widget)
+{
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+
+ g_queue_push_head (ctx->internal_event_q, (gpointer)widget);
+}
+
+gboolean
+cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev)
+{
+ if (widget && widget->xevent_handler)
+ return widget->xevent_handler(widget, xev);
+
+ return FALSE;
+}
--- /dev/null
+#ifndef _HAVE_CLTR_WIDGET_H
+#define _HAVE_CLTR_WIDGET_H
+
+typedef struct CltrWidget CltrWidget;
+
+#include "cltr.h"
+
+#define CLTR_WIDGET(w) ((CltrWidget*)(w))
+
+
+CltrWidget*
+cltr_widget_new(void);
+
+void
+cltr_widget_show(CltrWidget *widget);
+
+void
+cltr_widget_paint(CltrWidget *widget);
+
+
+gboolean
+cltr_widget_handle_xevent(CltrWidget *widget, XEvent *xev);
+
+
+
+void
+cltr_widget_show_all(CltrWidget *widget);
+
+void
+cltr_widget_queue_paint(CltrWidget *widget);
+
+void
+cltr_widget_add_child(CltrWidget *widget, CltrWidget *child, int x, int y);
+
+
+#endif
--- /dev/null
+#include "cltr-window.h"
+#include "cltr-private.h"
+
+static gboolean
+cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev);
+
+static void
+cltr_window_show(CltrWidget *widget);
+
+struct CltrWindow
+{
+ CltrWidget widget;
+ Window xwin;
+ CltrWidget *focused_child;
+};
+
+CltrWidget*
+cltr_window_new(int width, int height)
+{
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+ CltrWindow *win;
+
+ win = util_malloc0(sizeof(CltrWindow));
+
+ win->widget.width = width;
+ win->widget.height = height;
+ win->widget.show = cltr_window_show;
+ win->widget.xevent_handler = cltr_window_handle_xevent;
+
+ win->xwin = XCreateSimpleWindow(CltrCntx.xdpy,
+ CltrCntx.xwin_root,
+ 0, 0,
+ width, height,
+ 0, 0, WhitePixel(CltrCntx.xdpy,
+ CltrCntx.xscreen));
+
+ XSelectInput(CltrCntx.xdpy, win->xwin,
+ StructureNotifyMask|ExposureMask|
+ KeyPressMask|PropertyChangeMask);
+
+ glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context);
+
+ /* All likely better somewhere else */
+
+ /* view port */
+ glViewport (0, 0, width, height);
+ glMatrixMode (GL_PROJECTION);
+ glLoadIdentity ();
+ glOrtho (0, width, height, 0, -1, 1); /* 2d */
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ ctx->window = CLTR_WIDGET(win);
+
+ return CLTR_WIDGET(win);
+}
+
+Window
+cltr_window_xwin(CltrWindow *win)
+{
+ return win->xwin;
+}
+
+static void
+cltr_window_show(CltrWidget *widget)
+{
+ ClutterMainContext *ctx = CLTR_CONTEXT();
+ CltrWindow *win = CLTR_WINDOW(widget);
+
+ /* XXX set focused call */
+ if (widget->children)
+ {
+ win->focused_child = g_list_nth_data(widget->children, 0);
+ }
+
+ XMapWindow(ctx->xdpy, win->xwin);
+}
+
+static gboolean
+cltr_window_handle_xevent (CltrWidget *widget, XEvent *xev)
+{
+ CltrWindow *win = CLTR_WINDOW(widget);
+
+ /* XXX handle exposes here too */
+
+ if (xev->type == Expose)
+ {
+ ;
+ }
+
+ /* XXX Very basic - assumes we are only interested in mouse clicks */
+ if (win->focused_child)
+ return cltr_widget_handle_xevent(win->focused_child, xev);
+
+ return FALSE;
+}
+
+/* window only */
+
+
+
--- /dev/null
+#ifndef _HAVE_CLTR_WINDOW_H
+#define _HAVE_CLTR_WINDOW_H
+
+#include "cltr.h"
+
+typedef struct CltrWindow CltrWindow;
+
+#define CLTR_WINDOW(w) ((CltrWindow*)(w))
+
+CltrWidget*
+cltr_window_new(int width, int height);
+
+Window
+cltr_window_xwin(CltrWindow *win);
+
+void
+cltr_window_paint(CltrWidget *widget);
+
+void
+cltr_window_add_widget(CltrWindow *win, CltrWidget *widget, int x, int y);
+
+
+#endif
#include "cltr.h"
-#include <X11/keysym.h>
-
-/* temp temp temp */
-
-float Zoom = 1.0;
-ClutterPhotoGrid *Grid = NULL;
-
-/* ************* */
-
-static gboolean
-x_event_prepare (GSource *source,
- gint *timeout)
-{
- Display *display = ((CltrXEventSource*)source)->display;
-
- *timeout = -1;
-
- return XPending (display);
-}
-
-static gboolean
-x_event_check (GSource *source)
-{
- CltrXEventSource *display_source = (CltrXEventSource*)source;
- gboolean retval;
-
- if (display_source->event_poll_fd.revents & G_IO_IN)
- retval = XPending (display_source->display);
- else
- retval = FALSE;
-
- return retval;
-}
-
-static gboolean
-x_event_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- Display *display = ((CltrXEventSource*)source)->display;
- CltrXEventFunc event_func = (CltrXEventFunc) callback;
-
- XEvent xev;
-
- if (XPending (display))
- {
- XNextEvent (display, &xev);
-
- if (event_func)
- (*event_func) (&xev, user_data);
- }
-
- return TRUE;
-}
-
-static const GSourceFuncs x_event_funcs = {
- x_event_prepare,
- x_event_check,
- x_event_dispatch,
- NULL
-};
-
-void
-cltr_dispatch_expose(XExposeEvent *xexpev)
-{
- cltr_photo_grid_redraw(Grid);
-}
-
-void
-cltr_dispatch_keypress(XKeyEvent *xkeyev)
-{
- KeySym kc;
-
- kc = XKeycodeToKeysym(xkeyev->display, xkeyev->keycode, 0);
-
- switch (kc)
- {
- case XK_Left:
- case XK_KP_Left:
- cltr_photo_grid_navigate(Grid, CLTR_WEST);
- break;
- case XK_Up:
- case XK_KP_Up:
- cltr_photo_grid_navigate(Grid, CLTR_NORTH);
- break;
- case XK_Right:
- case XK_KP_Right:
- cltr_photo_grid_navigate(Grid, CLTR_EAST);
- break;
- case XK_Down:
- case XK_KP_Down:
- cltr_photo_grid_navigate(Grid, CLTR_SOUTH);
- break;
- case XK_Return:
- cltr_photo_grid_activate_cell(Grid);
- break;
- default:
- CLTR_DBG("unhandled keysym");
- }
-}
-
-static void
-cltr_dispatch_x_event (XEvent *xevent,
- gpointer data)
-{
- /* Should actually forward on to focussed widget */
-
- switch (xevent->type)
- {
- case MapNotify:
- CLTR_DBG("Map Notify Event");
- break;
- case Expose:
- CLTR_DBG("Expose"); /* TODO COMPRESS */
- cltr_dispatch_expose(&xevent->xexpose);
- break;
- case KeyPress:
- CLTR_DBG("KeyPress");
- cltr_dispatch_keypress(&xevent->xkey);
- break;
- }
-}
-
-int
-cltr_init(int *argc, char ***argv)
-{
- int gl_attributes[] =
- {
- GLX_RGBA,
- GLX_DOUBLEBUFFER,
- GLX_RED_SIZE, 1,
- GLX_GREEN_SIZE, 1,
- GLX_BLUE_SIZE, 1,
- 0
- };
-
- XVisualInfo *vinfo;
-
- GMainContext *gmain_context;
- int connection_number;
- GSource *source;
- CltrXEventSource *display_source;
-
- g_thread_init (NULL);
- // XInitThreads ();
-
- if ((CltrCntx.xdpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
- {
- return 0;
- }
-
- CltrCntx.xscreen = DefaultScreen(CltrCntx.xdpy);
- CltrCntx.xwin_root = RootWindow(CltrCntx.xdpy, CltrCntx.xscreen);
-
- if ((vinfo = glXChooseVisual(CltrCntx.xdpy,
- CltrCntx.xscreen,
- gl_attributes)) == NULL)
- {
- fprintf(stderr, "Unable to find visual\n");
- return 0;
- }
-
- CltrCntx.gl_context = glXCreateContext(CltrCntx.xdpy, vinfo, 0, True);
-
- /* g_main loop stuff */
-
- gmain_context = g_main_context_default ();
-
- g_main_context_ref (gmain_context);
-
- connection_number = ConnectionNumber (CltrCntx.xdpy);
-
- source = g_source_new ((GSourceFuncs *)&x_event_funcs,
- sizeof (CltrXEventSource));
-
- display_source = (CltrXEventSource *)source;
-
- display_source->event_poll_fd.fd = connection_number;
- display_source->event_poll_fd.events = G_IO_IN;
- display_source->display = CltrCntx.xdpy;
-
- g_source_add_poll (source, &display_source->event_poll_fd);
- g_source_set_can_recurse (source, TRUE);
-
- g_source_set_callback (source,
- (GSourceFunc) cltr_dispatch_x_event,
- NULL /* no userdata */, NULL);
-
- g_source_attach (source, gmain_context);
- g_source_unref (source);
-
- return 1;
-}
-
-
-ClutterWindow*
-cltr_window_new(int width, int height)
-{
- ClutterWindow *win;
-
- win = util_malloc0(sizeof(ClutterWindow));
-
- win->width = width;
- win->height = height;
-
- win->xwin = XCreateSimpleWindow(CltrCntx.xdpy,
- CltrCntx.xwin_root,
- 0, 0,
- width, height,
- 0, 0, WhitePixel(CltrCntx.xdpy,
- CltrCntx.xscreen));
-
- XSelectInput(CltrCntx.xdpy, win->xwin,
- StructureNotifyMask|ExposureMask|
- KeyPressMask|PropertyChangeMask);
-
- glXMakeCurrent(CltrCntx.xdpy, win->xwin, CltrCntx.gl_context);
-
- /* All likely better somewhere else */
-
- /* view port */
- glViewport (0, 0, width, height);
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
- glOrtho (0, width, height, 0, -1, 1); /* 2d */
- glMatrixMode (GL_MODELVIEW);
- glLoadIdentity ();
-
- glEnable (GL_TEXTURE_2D);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
- return win;
-}
-
-void
-cltr_main_loop()
-{
- GMainLoop *loop;
-
- loop = g_main_loop_new (g_main_context_default (), FALSE);
-
- CLTR_MARK();
-
- g_main_loop_run (loop);
-
-}
-
-gboolean
-test_idle_cb(gpointer data)
-{
- static float angle = 0.0;
-
- glClear(GL_COLOR_BUFFER_BIT);
- glClearColor( 0.6, 0.6, 0.62, 1.0);
-
- glColor3f(0.0, 0.0, 0.0);
-
- glTranslatef( 0.0, 0.0, 0.0);
-
- /* get a copy of our untranformed matrix */
- glPushMatrix();
-
- /* Translate origin to rotation point */
- glTranslatef( 320.0, 240.0, 0.0);
-
- /* Rotate around Z axis */
- glRotatef ( angle, 0.0, 0.0, 1.0);
-
- /* Draw tranformed rect with origin at center */
- glRecti(-50, -50, 50, 50);
-
- /* Reset our un transformed matrix */
- glPopMatrix();
-
- glRecti(-50, -50, 50, 50);
-
- angle += 0.1;
-
- glXSwapBuffers(CltrCntx.xdpy, (Window)data);
-
- return TRUE;
-}
-
-
-
int
main(int argc, char **argv)
{
- ClutterPhotoGrid *grid = NULL;
- ClutterWindow *win = NULL;
- /*
- Pixbuf *p1, *p2, *p3;
-
- p1 = pixbuf_new(2000,2000);
- p2 = pixbuf_new(640,480);
- p3 = pixbuf_scale_down(p1, 512, 512);
-
- pixbuf_copy(p3, p2, 0,0, 1000, 1000,0,0);
+ CltrWidget *win = NULL, *grid = NULL;
- exit(1);
- */
if (argc < 2)
{
g_printerr("usage: '%s' <path to not too heavily populated image dir>\n"
win = cltr_window_new(640, 480);
- grid = cltr_photo_grid_new(win, 3, 3, argv[1]);
-
- Grid = grid; /* laaaaaazy globals */
-
- // cltr_photo_grid_redraw(grid);
-
- // g_idle_add(idle_cb, grid);
-
- // g_timeout_add (10, idle_cb, grid);
-
- // g_idle_add(test_idle_cb, (gpointer)win->xwin);
-
- XFlush(CltrCntx.xdpy);
+ grid = cltr_photo_grid_new(640, 480, 3, 3, argv[1]);
- XMapWindow(CltrCntx.xdpy, win->xwin);
+ cltr_widget_add_child(win, grid, 0, 0);
- XFlush(CltrCntx.xdpy);
+ cltr_widget_show_all(win);
cltr_main_loop();
#include <math.h>
#include <X11/Xlib.h>
+#include <X11/keysym.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include "pixbuf.h"
#include "fonts.h"
-#define CLTR_WANT_DEBUG 1
-
-#if (CLTR_WANT_DEBUG)
-
-#define CLTR_DBG(x, a...) \
- g_printerr ( __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a)
-
-#define CLTR_GLERR() \
- { \
- GLenum err = glGetError (); /* Roundtrip */ \
- if (err != GL_NO_ERROR) \
- { \
- g_printerr (__FILE__ ": GL Error: %x [at %s:%d]\n", \
- err, __func__, __LINE__); \
- } \
- }
-
-#else
-
-#define CLTR_DBG(x, a...) do {} while (0)
-#define CLTR_GLERR() do {} while (0)
-
-#endif
-
-#define CLTR_MARK() CLTR_DBG("mark")
-
-typedef struct CltrTexturePool CltrTexturePool;
-
-struct CltrTexturePool
-{
- GList *texture_items;
- gint n_texture_items;
- GLuint *gl_textures;
-};
-
-typedef struct ClutterMainContext ClutterMainContext;
-
-struct ClutterMainContext
-{
- Display *xdpy;
- Window xwin_root;
- int xscreen;
- GC xgc;
- GLXContext gl_context;
- CltrTexturePool texture_pool;
-};
-
typedef enum CltrDirection
{
CLTR_NORTH,
}
CltrDirection;
-typedef struct ClutterWindow ClutterWindow;
-
-struct ClutterWindow
-{
- Window xwin;
- int width;
- int height;
-};
-
-ClutterMainContext CltrCntx;
-
-/* Event Loop Integration */
-
-typedef void (*CltrXEventFunc) (XEvent *xev, gpointer user_data);
-
-typedef struct
-{
- GSource source;
- Display *display;
- GPollFD event_poll_fd;
-}
-CltrXEventSource;
-
/* texture stuff */
-typedef struct CltrTexture CltrTexture;
-
-struct CltrTexture
-{
- Pixbuf *pixb;
-
- int width, height;
-
- int n_x_tiles, n_y_tiles;
- int *tile_x_position, *tile_x_size, *tile_x_waste;
- int *tile_y_position, *tile_y_size, *tile_y_waste;
-
- GLuint *tiles;
-
- gint refcnt;
-};
-
/* ******************* */
+#include "cltr-core.h"
#include "cltr-texture.h"
+#include "cltr-events.h"
+#include "cltr-widget.h"
+#include "cltr-window.h"
+
#include "cltr-photo-grid.h"
#endif