summaryrefslogtreecommitdiff
path: root/popover
diff options
context:
space:
mode:
Diffstat (limited to 'popover')
-rw-r--r--popover/main_windows.c227
-rw-r--r--popover/popover.c174
-rw-r--r--popover/popover.h30
-rw-r--r--popover/popover_unix.c117
4 files changed, 0 insertions, 548 deletions
diff --git a/popover/main_windows.c b/popover/main_windows.c
deleted file mode 100644
index 24c941a..0000000
--- a/popover/main_windows.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// 9 october 2014
-#include "../wininclude_windows.h"
-#include "popover.h"
-
-// #qo LIBS: user32 kernel32 gdi32
-
-// TODO
-// - should the parent window appear deactivated?
-
-HWND popoverWindow;
-
-void xpanic(char *msg, DWORD err)
-{
- printf("%d | %s\n", err, msg);
- abort();
-}
-
-popover *p;
-
-HRGN makePopoverRegion(HDC dc, LONG width, LONG height)
-{
- popoverPoint ppt[20];
- POINT pt[20];
- int i, n;
- HRGN region;
-
- n = popoverMakeFramePoints(p, (intptr_t) width, (intptr_t) height, ppt);
- for (i = 0; i < n; i++) {
- pt[i].x = (LONG) (ppt[i].x);
- pt[i].y = (LONG) (ppt[i].y);
- }
-
- if (BeginPath(dc) == 0)
- xpanic("error beginning path for Popover shape", GetLastError());
- if (Polyline(dc, pt, n) == 0)
- xpanic("error drawing lines in Popover shape", GetLastError());
- if (EndPath(dc) == 0)
- xpanic("error ending path for Popover shape", GetLastError());
- region = PathToRegion(dc);
- if (region == NULL)
- xpanic("error converting Popover shape path to region", GetLastError());
- return region;
-}
-
-#define msgPopoverPrepareLeftRight (WM_APP+50)
-#define msgPopoverPrepareTopBottom (WM_APP+51)
-
-LRESULT CALLBACK popoverproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- PAINTSTRUCT ps;
- HDC dc;
- HRGN region;
- RECT r;
- LONG width;
- LONG height;
- WINDOWPOS *wp;
- HBRUSH brush;
-
- switch (uMsg) {
- case WM_NCPAINT:
- if (GetWindowRect(hwnd, &r) == 0)
- xpanic("error getting Popover window rect for shape redraw", GetLastError());
- width = r.right - r.left;
- height = r.bottom - r.top;
- dc = GetWindowDC(hwnd);
- if (dc == NULL)
- xpanic("error getting Popover window DC for drawing border", GetLastError());
- region = makePopoverRegion(dc, width, height);
- // don't call FillRgn(); WM_ERASEBKGND seems to do this to the non-client area for us already :S (TODO confirm)
- // TODO arrow is black in wine
- brush = (HBRUSH) GetStockObject(BLACK_BRUSH);
- if (brush == NULL)
- xpanic("error getting Popover border brush", GetLastError());
- if (FrameRgn(dc, region, brush, 1, 1) == 0)
- xpanic("error drawing Popover border", GetLastError());
- if (DeleteObject(region) == 0)
- xpanic("error deleting Popover shape region", GetLastError());
- if (ReleaseDC(hwnd, dc) == 0)
- xpanic("error releasing Popover window DC for shape drawing", GetLastError());
- return 0;
- case WM_WINDOWPOSCHANGED:
- // this must be here; if it's in WM_NCPAINT weird things happen (see http://stackoverflow.com/questions/26288303/why-is-my-client-rectangle-drawing-behaving-bizarrely-pictures-provided-if-i-t)
- wp = (WINDOWPOS *) lParam;
- if ((wp->flags & SWP_NOSIZE) == 0) {
- dc = GetWindowDC(hwnd);
- if (dc == NULL)
- xpanic("error getting Popover window DC for reshaping", GetLastError());
- region = makePopoverRegion(dc, wp->cx, wp->cy);
- if (SetWindowRgn(hwnd, region, TRUE) == 0)
- xpanic("error setting Popover shape", GetLastError());
- // don't delete the region; the window manager owns it now
- if (ReleaseDC(hwnd, dc) == 0)
- xpanic("error releasing Popover window DC for reshaping", GetLastError());
- }
- break; // defer to DefWindowProc()
- case WM_NCCALCSIZE:
- {
- RECT *r = (RECT *) lParam;
- NCCALCSIZE_PARAMS *np = (NCCALCSIZE_PARAMS *) lParam;
- popoverRect pr;
-
- if (wParam != FALSE)
- r = &np->rgrc[0];
- pr.left = (intptr_t) (r->left);
- pr.top = (intptr_t) (r->top);
- pr.right = (intptr_t) (r->right);
- pr.bottom = (intptr_t) (r->bottom);
- popoverWindowSizeToClientSize(p, &pr);
- r->left = (LONG) (pr.left);
- r->top = (LONG) (pr.top);
- r->right = (LONG) (pr.right);
- r->bottom = (LONG) (pr.bottom);
- return 0;
- }
- case WM_PAINT:
- dc = BeginPaint(hwnd, &ps);
- GetClientRect(hwnd, &r);
- FillRect(dc, &r, GetSysColorBrush(COLOR_ACTIVECAPTION));
- FrameRect(dc, &r, GetStockPen(WHITE_BRUSH));
- EndPaint(hwnd, &ps);
- return 0;
- case msgPopoverPrepareLeftRight:
- case msgPopoverPrepareTopBottom:
- // TODO window edge detection
- {
- RECT r;
- LONG width = 200, height = 200;
- popoverRect control;
- uintptr_t side;
- popoverRect out;
-
- if (GetWindowRect((HWND) wParam, &r) == 0)
- xpanic("error getting window rect of Popover target", GetLastError());
- control.left = (intptr_t) (r.left);
- control.top = (intptr_t) (r.top);
- control.right = (intptr_t) (r.right);
- control.bottom = (intptr_t) (r.bottom);
- switch (uMsg) {
- case msgPopoverPrepareLeftRight:
- side = popoverPointLeft;
- break;
- case msgPopoverPrepareTopBottom:
- side = popoverPointTop;
- break;
- }
- out = popoverPointAt(p, control, (intptr_t) width, (intptr_t) height, side);
- if (MoveWindow(hwnd, out.left, out.top, out.right - out.left, out.bottom - out.top, TRUE) == 0)
- xpanic("error repositioning Popover", GetLastError());
- }
- return 0;
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-}
-
-HWND button;
-
-LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- switch (uMsg) {
- case WM_COMMAND:
- if (HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == 100) {
- SendMessageW(popoverWindow, msgPopoverPrepareLeftRight, (WPARAM) button, 0);
- ShowWindow(popoverWindow, SW_SHOW);
- UpdateWindow(popoverWindow);
- return 0;
- }
- break;
- case WM_CLOSE:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProcW(hwnd, uMsg, wParam, lParam);
-}
-
-int main(int argc, char *argv[])
-{
- WNDCLASSW wc;
- HWND mainwin;
- MSG msg;
-
- p = popoverDataNew(NULL);
- // TODO null check
-
- ZeroMemory(&wc, sizeof (WNDCLASSW));
- wc.lpszClassName = L"popover";
- wc.lpfnWndProc = popoverproc;
- wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
- wc.style = CS_DROPSHADOW | CS_NOCLOSE;
- if (RegisterClassW(&wc) == 0)
- abort();
- popoverWindow = CreateWindowExW(WS_EX_TOPMOST,
- L"popover", L"",
- WS_POPUP,
- 0, 0, 150, 100,
- NULL, NULL, NULL, NULL);
- if (popoverWindow == NULL)
- abort();
-
- ZeroMemory(&wc, sizeof (WNDCLASSW));
- wc.lpszClassName = L"mainwin";
- wc.lpfnWndProc = wndproc;
- wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
- if (RegisterClassW(&wc) == 0)
- abort();
- mainwin = CreateWindowExW(0,
- L"mainwin", L"Main Window",
- WS_OVERLAPPEDWINDOW,
- 0, 0, 150, 100,
- NULL, NULL, NULL, NULL);
- if (mainwin == NULL)
- abort();
- button = CreateWindowExW(0,
- L"button", L"Click Me",
- BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
- 20, 20, 100, 40,
- mainwin, (HMENU) 100, NULL, NULL);
- if (button == NULL)
- abort();
- ShowWindow(mainwin, SW_SHOWDEFAULT);
- if (UpdateWindow(mainwin) == 0)
- abort();
- while (GetMessageW(&msg, NULL, 0, 0) > 0) {
- TranslateMessage(&msg);
- DispatchMessageW(&msg);
- }
- return 0;
-}
diff --git a/popover/popover.c b/popover/popover.c
deleted file mode 100644
index 2c2bf66..0000000
--- a/popover/popover.c
+++ /dev/null
@@ -1,174 +0,0 @@
-// 9 october 2014
-#include <stdlib.h>
-#include <stdint.h>
-#include "popover.h"
-
-#define ARROWHEIGHT 8
-#define ARROWWIDTH 8 /* should be the same for smooth lines on Windows (TODO is there a better/nicer looking way?) */
-
-struct popover {
- void *gopopover;
-
- // a nice consequence of this design is that it allows four arrowheads to jut out at once; in practice only one will ever be used, but hey — simple implementation!
- intptr_t arrowLeft;
- intptr_t arrowTop;
- intptr_t arrowRight;
- intptr_t arrowBottom;
-};
-
-popover *popoverDataNew(void *gopopover)
-{
- popover *p;
-
- p = (popover *) malloc(sizeof (popover));
- if (p != NULL) {
- p->gopopover = gopopover;
- p->arrowLeft = -1;
- p->arrowTop = 20;//TODO-1;
- p->arrowRight = -1;
- p->arrowBottom = -1;
- }
- return p;
-}
-
-int popoverMakeFramePoints(popover *p, intptr_t width, intptr_t height, popoverPoint pt[20])
-{
- int n;
- intptr_t xmax, ymax;
-
- n = 0;
-
- // figure out the xmax and ymax of the box
- xmax = width;
- if (p->arrowRight >= 0)
- xmax -= ARROWWIDTH;
- ymax = height;
- if (p->arrowBottom >= 0)
- ymax -= ARROWHEIGHT;
-
- // the first point is either at (0,0), (0,arrowHeight), (arrowWidth,0), or (arrowWidth,arrowHeight)
- pt[n].x = 0;
- if (p->arrowLeft >= 0)
- pt[n].x = ARROWWIDTH;
- pt[n].y = 0;
- if (p->arrowTop >= 0)
- pt[n].y = ARROWHEIGHT;
- n++;
-
- // the left side
- pt[n].x = pt[n - 1].x;
- if (p->arrowLeft >= 0) {
- pt[n].y = pt[n - 1].y + p->arrowLeft;
- n++;
- pt[n].x = pt[n - 1].x - ARROWWIDTH;
- pt[n].y = pt[n - 1].y + ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x + ARROWWIDTH;
- pt[n].y = pt[n - 1].y + ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x;
- }
- pt[n].y = ymax;
- n++;
-
- // the bottom side
- pt[n].y = pt[n - 1].y;
- if (p->arrowBottom >= 0) {
- pt[n].x = pt[n - 1].x + p->arrowBottom;
- n++;
- pt[n].x = pt[n - 1].x + ARROWWIDTH;
- pt[n].y = pt[n - 1].y + ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x + ARROWWIDTH;
- pt[n].y = pt[n - 1].y - ARROWHEIGHT;
- n++;
- pt[n].y = pt[n - 1].y;
- }
- pt[n].x = xmax;
- n++;
-
- // the right side
- pt[n].x = pt[n - 1].x;
- if (p->arrowRight >= 0) {
- pt[n].y = pt[0].y + p->arrowRight + (ARROWHEIGHT * 2);
- n++;
- pt[n].x = pt[n - 1].x + ARROWWIDTH;
- pt[n].y = pt[n - 1].y - ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x - ARROWWIDTH;
- pt[n].y = pt[n - 1].y - ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x;
- }
- pt[n].y = pt[0].y;
- n++;
-
- // the top side
- pt[n].y = pt[n - 1].y;
- if (p->arrowTop >= 0) {
- pt[n].x = pt[0].x + p->arrowTop + (ARROWWIDTH * 2);
- n++;
- pt[n].x = pt[n - 1].x - ARROWWIDTH;
- pt[n].y = pt[n - 1].y - ARROWHEIGHT;
- n++;
- pt[n].x = pt[n - 1].x - ARROWWIDTH;
- pt[n].y = pt[n - 1].y + ARROWHEIGHT;
- n++;
- pt[n].y = pt[n - 1].y;
- }
- pt[n].x = pt[0].x;
- n++;
-
- return n;
-}
-
-void popoverWindowSizeToClientSize(popover *p, popoverRect *r)
-{
- r->left++;
- r->top++;
- r->right--;
- r->bottom--;
- if (p->arrowLeft >= 0)
- r->left += ARROWWIDTH;
- if (p->arrowRight >= 0)
- r->right -= ARROWWIDTH;
- if (p->arrowTop >= 0)
- r->top += ARROWHEIGHT;
- if (p->arrowBottom >= 0)
- r->bottom -= ARROWHEIGHT;
-}
-
-// TODO window edge detection
-popoverRect popoverPointAt(popover *p, popoverRect control, intptr_t width, intptr_t height, unsigned int side)
-{
- intptr_t x, y;
- popoverRect out;
-
- // account for border
- width += 2;
- height += 2;
- p->arrowLeft = -1;
- p->arrowRight = -1;
- p->arrowTop = -1;
- p->arrowBottom = -1;
- // TODO right and bottom
- switch (side) {
- case popoverPointLeft:
- width += ARROWWIDTH;
- p->arrowLeft = height / 2 - ARROWHEIGHT;
- x = control.right;
- y = control.top - ((height - (control.bottom - control.top)) / 2);
- break;
- case popoverPointTop:
- height += ARROWHEIGHT;
- p->arrowTop = width / 2 - ARROWWIDTH;
- x = control.left - ((width - (control.right - control.left)) / 2);
- y = control.bottom;
- break;
- }
- out.left = x;
- out.top = y;
- out.right = x + width;
- out.bottom = y + height;
- return out;
-}
diff --git a/popover/popover.h b/popover/popover.h
deleted file mode 100644
index 28220e4..0000000
--- a/popover/popover.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// 11 october 2014
-
-typedef struct popover popover;
-typedef struct popoverPoint popoverPoint;
-typedef struct popoverRect popoverRect;
-
-struct popoverPoint {
- intptr_t x;
- intptr_t y;
-};
-
-struct popoverRect {
- intptr_t left;
- intptr_t top;
- intptr_t right;
- intptr_t bottom;
-};
-
-// note the order: flipping sides is as easy as side ^ 1
-enum {
- popoverPointLeft,
- popoverPointRight,
- popoverPointTop,
- popoverPointBottom,
-};
-
-popover *popoverDataNew(void *);
-int popoverMakeFramePoints(popover *, intptr_t, intptr_t, popoverPoint[20]);
-void popoverWindowSizeToClientSize(popover *, popoverRect *);
-popoverRect popoverPointAt(popover *, popoverRect, intptr_t, intptr_t, unsigned int);
diff --git a/popover/popover_unix.c b/popover/popover_unix.c
deleted file mode 100644
index 0844844..0000000
--- a/popover/popover_unix.c
+++ /dev/null
@@ -1,117 +0,0 @@
-// 11 october 2014
-// #qo pkg-config: gtk+-3.0
-#include <gtk/gtk.h>
-
-#define GOPOPOVER_TYPE (goPopover_get_type())
-#define GOPOPOVER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GOPOPOVER_TYPE, goPopover))
-#define IS_GOPOPOVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GOPOPOVER_TYPE))
-#define GOPOPOVER_CLASS(class) (G_TYPE_CHECK_CLASS_CAST((class), GOPOPOVER_TYPE, goPopoverClass))
-#define IS_GOPOPOVER_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE((class), GOPOPOVER_TYPE))
-#define GOPOPOVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GOPOPOVER_TYPE, goPopoverClass))
-
-typedef struct goPopover goPopover;
-typedef struct goPopoverClass goPopoverClass;
-
-struct goPopover {
- GtkBin parent_instance;
- void *gocontainer;
- GdkWindow *gdkwin;
-};
-
-struct goPopoverClass {
- GtkBinClass parent_class;
-};
-
-G_DEFINE_TYPE(goPopover, goPopover, GTK_TYPE_BIN)
-
-static void goPopover_init(goPopover *p)
-{
- gtk_widget_set_has_window(GTK_WIDGET(p), TRUE);
-}
-
-static void goPopover_dispose(GObject *obj)
-{
- G_OBJECT_CLASS(goPopover_parent_class)->dispose(obj);
-}
-
-static void goPopover_finalize(GObject *obj)
-{
- G_OBJECT_CLASS(goPopover_parent_class)->finalize(obj);
-}
-
-static void goPopover_realize(GtkWidget *widget)
-{
- GdkWindowAttr attr;
- goPopover *p = GOPOPOVER(widget);
-
- attr.x = 0;
- attr.y = 0;
- attr.width = 200;
- attr.height = 200;
- attr.wclass = GDK_INPUT_OUTPUT;
- attr.event_mask = gtk_widget_get_events(GTK_WIDGET(p)) | GDK_POINTER_MOTION_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_EXPOSURE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
- attr.visual = gtk_widget_get_visual(GTK_WIDGET(p));
- attr.window_type = GDK_WINDOW_CHILD; // GtkPopover does this; TODO what does GtkWindow(GTK_WINDOW_POPUP) do?
- p->gdkwin = gdk_window_new(gtk_widget_get_parent_window(GTK_WIDGET(p)),
- &attr, GDK_WA_VISUAL);
- gtk_widget_set_window(GTK_WIDGET(p), p->gdkwin);
- gtk_widget_register_window(GTK_WIDGET(p), p->gdkwin);
- gtk_widget_set_realized(GTK_WIDGET(p), TRUE);
-}
-
-static void goPopover_map(GtkWidget *widget)
-{
- gdk_window_show(GOPOPOVER(widget)->gdkwin);
- GTK_WIDGET_CLASS(goPopover_parent_class)->map(widget);
-}
-
-static void goPopover_unmap(GtkWidget *widget)
-{
- gdk_window_hide(GOPOPOVER(widget)->gdkwin);
- GTK_WIDGET_CLASS(goPopover_parent_class)->unmap(widget);
-}
-
-static gboolean goPopover_draw(GtkWidget *widget, cairo_t *cr)
-{
- GtkStyleContext *context;
-
- context = gtk_widget_get_style_context(widget);
- gtk_render_background(context, cr, 0, 0, 200, 200);
- return TRUE;
-}
-
-static void goPopover_class_init(goPopoverClass *class)
-{
- G_OBJECT_CLASS(class)->dispose = goPopover_dispose;
- G_OBJECT_CLASS(class)->finalize = goPopover_finalize;
- GTK_WIDGET_CLASS(class)->realize = goPopover_realize;
- GTK_WIDGET_CLASS(class)->map = goPopover_map;
- GTK_WIDGET_CLASS(class)->unmap = goPopover_unmap;
- GTK_WIDGET_CLASS(class)->draw = goPopover_draw;
-}
-
-void buttonClicked(GtkWidget *button, gpointer data)
-{
- GtkWidget *popover;
-
- popover = g_object_new(GOPOPOVER_TYPE, NULL);
- gtk_widget_set_parent(popover, gtk_widget_get_parent(button));
- gtk_widget_show(popover);
-}
-
-int main(void)
-{
- GtkWidget *mainwin;
- GtkWidget *button;
-
- gtk_init(NULL, NULL);
- mainwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_resize(GTK_WINDOW(mainwin), 150, 50);
- g_signal_connect(mainwin, "destroy", gtk_main_quit, NULL);
- button = gtk_button_new_with_label("Click Me");
- g_signal_connect(button, "clicked", G_CALLBACK(buttonClicked), NULL);
- gtk_container_add(GTK_CONTAINER(mainwin), button);
- gtk_widget_show_all(mainwin);
- gtk_main();
- return 0;
-}