Пример #1
1
func finishNewTable(b *tablebase, ty reflect.Type) Table {
	id := C.newTable()
	t := &table{
		scroller:  newScroller(id, true), // border on Table
		tablebase: b,
		selected:  newEvent(),
	}
	t.fpreferredSize = t.xpreferredSize
	// also sets the delegate
	C.tableMakeDataSource(t.id, unsafe.Pointer(t))
	for i := 0; i < ty.NumField(); i++ {
		colname := ty.Field(i).Tag.Get("uicolumn")
		if colname == "" {
			colname = ty.Field(i).Name
		}
		cname := C.CString(colname)
		coltype := C.colTypeText
		editable := false
		switch {
		case ty.Field(i).Type == reflect.TypeOf((*image.RGBA)(nil)):
			coltype = C.colTypeImage
		case ty.Field(i).Type.Kind() == reflect.Bool:
			coltype = C.colTypeCheckbox
			editable = true
		}
		C.tableAppendColumn(t.id, C.intptr_t(i), cname, C.int(coltype), toBOOL(editable))
		C.free(unsafe.Pointer(cname)) // free now (not deferred) to conserve memory
	}
	return t
}
Пример #2
0
func finishNewTable(b *tablebase, ty reflect.Type) Table {
	widget := C.gtk_tree_view_new()
	t := &table{
		scroller:  newScroller(widget, true, true, false), // natively scrollable; has a border; no overlay
		tablebase: b,
		treeview:  (*C.GtkTreeView)(unsafe.Pointer(widget)),
		crtocol:   make(map[*C.GtkCellRendererToggle]int),
		selected:  newEvent(),
	}
	model := C.newTableModel(unsafe.Pointer(t))
	t.model = model
	t.modelgtk = (*C.GtkTreeModel)(unsafe.Pointer(model))
	t.selection = C.gtk_tree_view_get_selection(t.treeview)
	g_signal_connect(
		C.gpointer(unsafe.Pointer(t.selection)),
		"changed",
		C.GCallback(C.tableSelectionChanged),
		C.gpointer(unsafe.Pointer(t)))
	C.gtk_tree_view_set_model(t.treeview, t.modelgtk)
	for i := 0; i < ty.NumField(); i++ {
		colname := ty.Field(i).Tag.Get("uicolumn")
		if colname == "" {
			colname = ty.Field(i).Name
		}
		cname := togstr(colname)
		switch {
		case ty.Field(i).Type == reflect.TypeOf((*image.RGBA)(nil)):
			// can't use GDK_TYPE_PIXBUF here because it's a macro that expands to a function and cgo hates that
			t.types = append(t.types, C.gdk_pixbuf_get_type())
			C.tableAppendColumn(t.treeview, C.gint(i), cname,
				C.gtk_cell_renderer_pixbuf_new(), attribPixbuf)
		case ty.Field(i).Type.Kind() == reflect.Bool:
			t.types = append(t.types, C.G_TYPE_BOOLEAN)
			cr := C.gtk_cell_renderer_toggle_new()
			crt := (*C.GtkCellRendererToggle)(unsafe.Pointer(cr))
			t.crtocol[crt] = i
			g_signal_connect(C.gpointer(unsafe.Pointer(cr)),
				"toggled",
				C.GCallback(C.goTableModel_toggled),
				C.gpointer(unsafe.Pointer(t)))
			C.tableAppendColumn(t.treeview, C.gint(i), cname,
				cr, attribActive)
		default:
			t.types = append(t.types, C.G_TYPE_STRING)
			C.tableAppendColumn(t.treeview, C.gint(i), cname,
				C.gtk_cell_renderer_text_new(), attribText)
		}
		freegstr(cname) // free now (not deferred) to conserve memory
	}
	// and for some GtkTreeModel boilerplate
	t.nColumns = C.gint(ty.NumField())
	return t
}
Пример #3
0
func finishNewTable(b *tablebase, ty reflect.Type) Table {
	t := &table{
		_hwnd: C.newControl(C.xWC_LISTVIEW,
			C.LVS_REPORT|C.LVS_OWNERDATA|C.LVS_NOSORTHEADER|C.LVS_SHOWSELALWAYS|C.LVS_SINGLESEL|C.WS_HSCROLL|C.WS_VSCROLL|C.WS_TABSTOP,
			C.WS_EX_CLIENTEDGE), // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog)
		tablebase: b,
		hotrow:    -1,
		hotcol:    -1,
		pushedrow: -1,
		pushedcol: -1,
		selected:  newEvent(),
	}
	C.setTableSubclass(t._hwnd, unsafe.Pointer(t))
	// LVS_EX_FULLROWSELECT gives us selection across the whole row, not just the leftmost column; this makes the list view work like on other platforms
	// LVS_EX_SUBITEMIMAGES gives us images in subitems, which will be important when both images and checkboxes are added
	C.tableAddExtendedStyles(t._hwnd, C.LVS_EX_FULLROWSELECT|C.LVS_EX_SUBITEMIMAGES)
	// this must come after the subclass because it uses one of our private messages
	C.SendMessageW(t._hwnd, C.msgTableMakeInitialCheckboxImageList, 0, 0)
	for i := 0; i < ty.NumField(); i++ {
		C.tableAppendColumn(t._hwnd, C.int(i), toUTF16(ty.Field(i).Name))
	}
	t.colcount = C.int(ty.NumField())
	return t
}