Пример #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
//export goTableDataSource_getValue
func goTableDataSource_getValue(data unsafe.Pointer, row C.intptr_t, col C.intptr_t, outtype *C.int) unsafe.Pointer {
	t := (*table)(data)
	t.RLock()
	defer t.RUnlock()
	d := reflect.Indirect(reflect.ValueOf(t.data))
	datum := d.Index(int(row)).Field(int(col))
	switch {
	case datum.Type() == reflect.TypeOf((*image.RGBA)(nil)):
		*outtype = C.colTypeImage
		d := datum.Interface().(*image.RGBA)
		img := C.toTableImage(unsafe.Pointer(pixelData(d)), C.intptr_t(d.Rect.Dx()), C.intptr_t(d.Rect.Dy()), C.intptr_t(d.Stride))
		return unsafe.Pointer(img)
	case datum.Kind() == reflect.Bool:
		*outtype = C.colTypeCheckbox
		if datum.Bool() == true {
			// return a non-nil pointer
			// outtype isn't Go-side so it'll work
			return unsafe.Pointer(outtype)
		}
		return nil
	default:
		s := fmt.Sprintf("%v", datum)
		return unsafe.Pointer(C.CString(s))
	}
}
Пример #3
0
//export tableGetCell
func tableGetCell(data unsafe.Pointer, tnm *C.tableNM) C.LRESULT {
	t := (*table)(data)
	t.RLock()
	defer t.RUnlock()
	d := reflect.Indirect(reflect.ValueOf(t.data))
	datum := d.Index(int(tnm.row)).Field(int(tnm.column))
	switch {
	case datum.Type() == reflect.TypeOf((*image.RGBA)(nil)):
		i := datum.Interface().(*image.RGBA)
		hbitmap := C.toBitmap(unsafe.Pointer(i), C.intptr_t(i.Rect.Dx()), C.intptr_t(i.Rect.Dy()))
		bitmap := C.uintptr_t(uintptr(unsafe.Pointer(hbitmap)))
		t.freeLock.Lock()
		t.free[bitmap] = true // bitmap freed with C.freeBitmap()
		t.freeLock.Unlock()
		return C.LRESULT(bitmap)
	case datum.Kind() == reflect.Bool:
		if datum.Bool() == true {
			return C.TRUE
		}
		return C.FALSE
	default:
		s := fmt.Sprintf("%v", datum)
		text := C.uintptr_t(uintptr(unsafe.Pointer(toUTF16(s))))
		t.freeLock.Lock()
		t.free[text] = false // text freed with C.free()
		t.freeLock.Unlock()
		return C.LRESULT(text)
	}
}
Пример #4
0
func (l *label) commitResize(c *allocation, d *sizing) {
	if !l.standalone && c.neighbor != nil {
		c.neighbor.getAuxResizeInfo(d)
		if d.neighborAlign.baseline != 0 { // no adjustment needed if the given control has no baseline
			// in order for the baseline value to be correct, the label MUST BE AT THE HEIGHT THAT OS X WANTS IT TO BE!
			// otherwise, the baseline calculation will be relative to the bottom of the control, and everything will be wrong
			origsize := C.controlPreferredSize(l._id)
			c.height = int(origsize.height)
			newrect := C.struct_xrect{
				x:      C.intptr_t(c.x),
				y:      C.intptr_t(c.y),
				width:  C.intptr_t(c.width),
				height: C.intptr_t(c.height),
			}
			ourAlign := C.alignmentInfo(l._id, newrect)
			// we need to find the exact Y positions of the baselines
			// fortunately, this is easy now that (x,y) is the bottom-left corner
			thisbasey := ourAlign.rect.y + ourAlign.baseline
			neighborbasey := d.neighborAlign.rect.y + d.neighborAlign.baseline
			// now the amount we have to move the label down by is easy to find
			yoff := neighborbasey - thisbasey
			// and we just add that
			c.y += int(yoff)
		}
		// in the other case, the most correct thing would be for Label to be aligned to the alignment rect, but I can't get this working, and it looks fine as it is anyway
	}
	basecommitResize(l, c, d)
}
Пример #5
0
func (s *sysData) setRect(x int, y int, width int, height int, winheight int) error {
	// winheight - y because (0,0) is the bottom-left corner of the window and not the top-left corner
	// (winheight - y) - height because (x, y) is the bottom-left corner of the control and not the top-left
	C.setRect(s.id,
		C.intptr_t(x), C.intptr_t((winheight-y)-height),
		C.intptr_t(width), C.intptr_t(height))
	return nil
}
Пример #6
0
func (s *sysData) setAreaSize(width int, height int) {
	ret := make(chan struct{})
	defer close(ret)
	uitask <- func() {
		C.setAreaSize(s.id, C.intptr_t(width), C.intptr_t(height))
		ret <- struct{}{}
	}
	<-ret
}
Пример #7
0
func (s *sysData) setWindowSize(width int, height int) error {
	ret := make(chan struct{})
	defer close(ret)
	uitask <- func() {
		C.windowSetContentSize(s.id, C.intptr_t(width), C.intptr_t(height))
		ret <- struct{}{}
	}
	<-ret
	return nil
}
Пример #8
0
func (a *area) Repaint(r image.Rectangle) {
	var s C.struct_xrect

	r = image.Rect(0, 0, a.width, a.height).Intersect(r)
	if r.Empty() {
		return
	}
	s.x = C.intptr_t(r.Min.X)
	s.y = C.intptr_t(r.Min.Y)
	s.width = C.intptr_t(r.Dx())
	s.height = C.intptr_t(r.Dy())
	C.areaRepaint(a.id, s)
}
Пример #9
0
//export containerResized
func containerResized(data unsafe.Pointer) {
	c := (*container)(data)
	d := beginResize()
	// TODO make this a parameter
	b := C.containerBounds(c.id)
	if c.margined {
		b.x += C.intptr_t(macXMargin)
		b.y += C.intptr_t(macYMargin)
		b.width -= C.intptr_t(macXMargin) * 2
		b.height -= C.intptr_t(macYMargin) * 2
	}
	c.resize(int(b.x), int(b.y), int(b.width), int(b.height), d)
}
Пример #10
0
func newWindow(title string, width int, height int, control Control) *window {
	id := C.newWindow(C.intptr_t(width), C.intptr_t(height))
	ctitle := C.CString(title)
	defer C.free(unsafe.Pointer(ctitle))
	C.windowSetTitle(id, ctitle)
	w := &window{
		id:        id,
		closing:   newEvent(),
		container: newContainer(control),
	}
	C.windowSetDelegate(w.id, unsafe.Pointer(w))
	C.windowSetContentView(w.id, w.container.id)
	return w
}
Пример #11
0
func (s *sysData) commitResize(c *allocation, d *sysSizeData) {
	if s.ctype == c_label && !s.alternate && c.neighbor != nil {
		c.neighbor.getAuxResizeInfo(d)
		if d.neighborAlign.baseline != 0 { // no adjustment needed if the given control has no baseline
			// in order for the baseline value to be correct, the label MUST BE AT THE HEIGHT THAT OS X WANTS IT TO BE!
			// otherwise, the baseline calculation will be relative to the bottom of the control, and everything will be wrong
			origsize := C.controlPrefSize(s.id)
			c.height = int(origsize.height)
			newrect := C.struct_xrect{
				x:      C.intptr_t(c.x),
				y:      C.intptr_t(c.y),
				width:  C.intptr_t(c.width),
				height: C.intptr_t(c.height),
			}
			ourAlign := C.alignmentInfo(s.id, newrect)
			// we need to find the exact Y positions of the baselines
			// fortunately, this is easy now that (x,y) is the bottom-left corner
			thisbasey := ourAlign.alignmentRect.y + ourAlign.baseline
			neighborbasey := d.neighborAlign.alignmentRect.y + d.neighborAlign.baseline
			// now the amount we have to move the label down by is easy to find
			yoff := neighborbasey - thisbasey
			// and we just add that
			c.y += int(yoff)
		}
		// TODO if there's no baseline, the alignment should be to the top /of the alignment rect/, not the frame
	}
	C.setRect(s.id, C.intptr_t(c.x), C.intptr_t(c.y), C.intptr_t(c.width), C.intptr_t(c.height))
}
Пример #12
0
//export doPaint
func doPaint(xrect *C.RECT, hscroll C.int, vscroll C.int, data unsafe.Pointer, dx *C.intptr_t, dy *C.intptr_t) unsafe.Pointer {
	a := (*area)(data)
	// both Windows RECT and Go image.Rect are point..point, so the following is correct
	cliprect := image.Rect(int(xrect.left), int(xrect.top), int(xrect.right), int(xrect.bottom))
	cliprect = cliprect.Add(image.Pt(int(hscroll), int(vscroll))) // adjust by scroll position
	// make sure the cliprect doesn't fall outside the size of the Area
	cliprect = cliprect.Intersect(image.Rect(0, 0, a.width, a.height))
	if !cliprect.Empty() { // we have an update rect
		i := a.handler.Paint(cliprect)
		*dx = C.intptr_t(i.Rect.Dx())
		*dy = C.intptr_t(i.Rect.Dy())
		return unsafe.Pointer(i)
	}
	return nil
}
Пример #13
0
//export areaView_drawRect
func areaView_drawRect(self C.id, rect C.struct_xrect) {
	s := getSysData(self)
	// no need to clear the clip rect; the NSScrollView does that for us (see the setDrawsBackground: call in objc_darwin.m)
	// rectangles in Cocoa are origin/size, not point0/point1; if we don't watch for this, weird things will happen when scrolling
	cliprect := image.Rect(int(rect.x), int(rect.y), int(rect.x+rect.width), int(rect.y+rect.height))
	max := C.frame(self)
	cliprect = image.Rect(0, 0, int(max.width), int(max.height)).Intersect(cliprect)
	if cliprect.Empty() { // no intersection; nothing to paint
		return
	}
	i := s.handler.Paint(cliprect)
	C.drawImage(
		unsafe.Pointer(pixelData(i)), C.intptr_t(i.Rect.Dx()), C.intptr_t(i.Rect.Dy()), C.intptr_t(i.Stride),
		C.intptr_t(cliprect.Min.X), C.intptr_t(cliprect.Min.Y))
}
Пример #14
0
//export goTableDataSource_getRowCount
func goTableDataSource_getRowCount(data unsafe.Pointer) C.intptr_t {
	t := (*table)(data)
	t.RLock()
	defer t.RUnlock()
	d := reflect.Indirect(reflect.ValueOf(t.data))
	return C.intptr_t(d.Len())
}
Пример #15
0
func newWindow(title string, width int, height int, control Control) *window {
	id := C.newWindow(C.intptr_t(width), C.intptr_t(height))
	ctitle := C.CString(title)
	defer C.free(unsafe.Pointer(ctitle))
	C.windowSetTitle(id, ctitle)
	w := &window{
		id:      id,
		closing: newEvent(),
		child:   control,
	}
	C.windowSetDelegate(w.id, unsafe.Pointer(w))
	w.container = newContainer(w.child.resize)
	w.child.setParent(w.container.parent())
	C.windowSetContentView(w.id, w.container.id)
	// trigger an initial resize
	return w
}
Пример #16
0
//export areaView_drawRect
func areaView_drawRect(self C.id, rect C.struct_xrect, data unsafe.Pointer) {
	a := (*area)(data)
	// no need to clear the clip rect; the NSScrollView does that for us (see the setDrawsBackground: call in objc_darwin.m)
	// rectangles in Cocoa are origin/size, not point0/point1; if we don't watch for this, weird things will happen when scrolling
	cliprect := image.Rect(int(rect.x), int(rect.y), int(rect.x+rect.width), int(rect.y+rect.height))
	cliprect = image.Rect(0, 0, int(a.width), int(a.height)).Intersect(cliprect)
	if cliprect.Empty() { // no intersection; nothing to paint
		return
	}
	i := a.handler.Paint(cliprect)
	success := C.drawImage(
		unsafe.Pointer(pixelData(i)), C.intptr_t(i.Rect.Dx()), C.intptr_t(i.Rect.Dy()), C.intptr_t(i.Stride),
		C.intptr_t(cliprect.Min.X), C.intptr_t(cliprect.Min.Y))
	if success == C.NO {
		panic("error drawing into Area (exactly what is unknown)")
	}
}
Пример #17
0
func (s *sysData) setProgress(percent int) {
	ret := make(chan struct{})
	defer close(ret)
	uitask <- func() {
		C.setProgress(s.id, C.intptr_t(percent))
		ret <- struct{}{}
	}
	<-ret
}
Пример #18
0
func (t *table) Unlock() {
	t.unlock()
	// there's a possibility that user actions can happen at this point, before the view is updated
	// alas, this is something we have to deal with, because Unlock() can be called from any thread
	go func() {
		Do(func() {
			t.RLock()
			defer t.RUnlock()
			C.gotableSetRowCount(t.hwnd, C.intptr_t(reflect.Indirect(reflect.ValueOf(t.data)).Len()))
		})
	}()
}
Пример #19
0
//export hookGoValueReadField
func hookGoValueReadField(enginep, foldp unsafe.Pointer, reflectIndex, getIndex, setIndex C.int, resultdv *C.DataValue) {
	fold := ensureEngine(enginep, foldp)

	var field reflect.Value
	if getIndex >= 0 {
		field = reflect.ValueOf(fold.gvalue).Method(int(getIndex)).Call(nil)[0]
	} else {
		field = deref(reflect.ValueOf(fold.gvalue)).Field(int(reflectIndex))
	}
	field = deref(field)

	// Cannot compare Type directly as field may be invalid (nil).
	if field.Kind() == reflect.Slice && field.Type() == typeObjSlice {
		// TODO Handle getters that return []qml.Object.
		// TODO Handle other GoValue slices (!= []qml.Object).
		resultdv.dataType = C.DTListProperty
		*(*unsafe.Pointer)(unsafe.Pointer(&resultdv.data)) = C.newListProperty(foldp, C.intptr_t(reflectIndex), C.intptr_t(setIndex))
		return
	}

	fieldk := field.Kind()
	if fieldk == reflect.Slice || fieldk == reflect.Struct && field.Type() != typeRGBA {
		if field.CanAddr() {
			field = field.Addr()
		} else if !hashable(field.Interface()) {
			t := reflect.ValueOf(fold.gvalue).Type()
			for t.Kind() == reflect.Ptr {
				t = t.Elem()
			}
			panic(fmt.Sprintf("cannot access unaddressable and unhashable struct value on interface field %s.%s; value: %#v", t.Name(), t.Field(int(reflectIndex)).Name, field.Interface()))
		}
	}
	var gvalue interface{}
	if field.IsValid() {
		gvalue = field.Interface()
	}

	// TODO Strings are being passed in an unsafe manner here. There is a
	// small chance that the field is changed and the garbage collector is run
	// before C++ has a chance to look at the data. We can solve this problem
	// by queuing up values in a stack, and cleaning the stack when the
	// idle timer fires next.
	packDataValue(gvalue, resultdv, fold.engine, jsOwner)
}
Пример #20
0
func (i *imagelist) Append(img *image.RGBA) {
	id := C.toImageListImage(
		unsafe.Pointer(pixelData(img)), C.intptr_t(img.Rect.Dx()), C.intptr_t(img.Rect.Dy()), C.intptr_t(img.Stride))
	i.list = append(i.list, id)
}
Пример #21
0
func (i *imagelist) Append(img *image.RGBA) {
	i.list = append(i.list, C.unscaledBitmap(unsafe.Pointer(img), C.intptr_t(img.Rect.Dx()), C.intptr_t(img.Rect.Dy())))
	i.width = append(i.width, img.Rect.Dx())
	i.height = append(i.height, img.Rect.Dy())
}
Пример #22
0
func dobasecommitResize(id C.id, c *allocation, d *sizing) {
	C.moveControl(id, C.intptr_t(c.x), C.intptr_t(c.y), C.intptr_t(c.width), C.intptr_t(c.height))
}
Пример #23
0
func (e *EventSource) SetData(data uintptr) {
	C.al_set_event_source_data((*C.ALLEGRO_EVENT_SOURCE)(unsafe.Pointer(e)), C.intptr_t(data))
}
Пример #24
0
func (c *controlSingleObject) xresize(x int, y int, width int, height int, d *sizing) {
	C.moveControl(c.id, C.intptr_t(x), C.intptr_t(y), C.intptr_t(width), C.intptr_t(height))
}
Пример #25
0
			combobox := C.makeCombobox(toBOOL(alternate))
			applyStandardControlFont(combobox)
			addControl(parentWindow, combobox)
			return combobox
		},
		show: controlShow,
		hide: controlHide,
		text: func(what C.id, alternate bool) C.id {
			return C.comboboxText(what, toBOOL(alternate))
		},
		append: func(id C.id, what string, alternate bool) {
			C.comboboxAppend(id, toBOOL(alternate), toNSString(what))
		},
		insertBefore: func(id C.id, what string, before int, alternate bool) {
			C.comboboxInsertBefore(id, toBOOL(alternate),
				toNSString(what), C.intptr_t(before))
		},
		selIndex: func(id C.id) int {
			return int(C.comboboxSelectedIndex(id))
		},
		delete: func(id C.id, index int) {
			C.comboboxDelete(id, C.intptr_t(index))
		},
		len: func(id C.id) int {
			return int(C.comboboxLen(id))
		},
	},
	c_lineedit: &classData{
		make: func(parentWindow C.id, alternate bool, s *sysData) C.id {
			lineedit := C.makeLineEdit(toBOOL(alternate))
			applyStandardControlFont(lineedit)
Пример #26
0
func (t *table) Select(index int) {
	t.RLock()
	defer t.RUnlock()
	C.tableSelect(t.id, C.intptr_t(index))
}
Пример #27
0
func (a *area) OpenTextFieldAt(x, y int) {
	if x < 0 || x >= a.width || y < 0 || y >= a.height {
		panic(fmt.Errorf("point (%d,%d) outside Area in Area.OpenTextFieldAt()", x, y))
	}
	C.areaTextFieldOpen(a.id, a.textfield, C.intptr_t(x), C.intptr_t(y))
}
Пример #28
0
func (a *area) SetSize(width, height int) {
	a.width = width
	a.height = height
	// set the frame size to set the area's effective size on the Cocoa side
	C.moveControl(a.id, 0, 0, C.intptr_t(a.width), C.intptr_t(a.height))
}
Пример #29
0
func (s *spinbox) resize(x int, y int, width int, height int, d *sizing) {
	// TODO
	C.moveControl(s.textfield(), C.intptr_t(x), C.intptr_t(y), C.intptr_t(width-20), C.intptr_t(height))
	C.moveControl(s.stepper(), C.intptr_t(x+width-15), C.intptr_t(y), C.intptr_t(15), C.intptr_t(height))
}