作者:sjn197
项目:u
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
}
作者:sjn197
项目:u
//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))
}
}
作者:sjn197
项目:u
//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)
}
}
作者:NotBadPa
项目:u
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)
}
作者:BlackWidowMake
项目:u
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
}
作者:BlackWidowMake
项目:u
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
}
作者:BlackWidowMake
项目:u
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
}
作者:sjn197
项目:u
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)
}
作者:sjn197
项目:u
//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)
}
作者:NotBadPa
项目:u
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
}
作者:UIKit
项目:u
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))
}
作者:sjn197
项目:u
//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
}
作者:UIKit
项目:u
//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))
}
作者:sjn197
项目:u
//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())
}
作者:sjn197
项目:u
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
}
作者:sjn197
项目:u
//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)")
}
}
作者:BlackWidowMake
项目:u
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
}
作者:sjn197
项目:u
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()))
})
}()
}
作者:pmeid
项目:Arianrho
//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)
}
作者:NotBadPa
项目:u
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)
}