Best Rod code snippet using main.size
uiLibFlexbox.go
Source:uiLibFlexbox.go
...27 // Can be nil.28 Element UILayoutElement29 // If there is a surplus, these are used to distribute it.30 Grow int3231 // If there is a deficit, these are used to distribute it (along with minimum sizes)32 // DEFAULTS TO 1 IN CSS33 Shrink int3234 // If *non-zero*, then this specifies the "initial share size" of this element.35 // Useful when Element is nil.36 Basis int3237 // Slightly non-standard extension (or is it?) for cases where Basis would be used to pad a problematic element38 MinBasis int3239 // Used to order the flexboxes visually. The Z-Order remains the index order.40 Order int41 // If the container should respect the minimum size of this slot.42 // DEFAULTS TO TRUE IN CSS (settable to false by overriding min w/h), BUT THIS IS REALLY STUPID B/C IT IGNORES SIZE CONSTRAINTS, SO LET'S NOT DO THAT43 RespectMinimumSize bool44}45type fyFlexboxSlotlike interface {46 fyMainCrossSizeForMainCrossLimits(limits frenyard.Vec2i, vertical bool, debug bool) frenyard.Vec2i47 fyGrowShrink() (int32, int32)48 fyCalcBasis(cross int32, vertical bool) int3249 fyGetOrder() int50 fyRespectMinimumSize() bool51}52func (slot FlexboxSlot) fyMainCrossSizeForMainCrossLimits(limits frenyard.Vec2i, vertical bool, debug bool) frenyard.Vec2i {53 if slot.Element == nil {54 return frenyard.Vec2i{}55 }56 if debug {57 fmt.Print("?")58 }59 mainCrossSize := slot.Element.FyLSizeForLimits(limits.ConditionalTranspose(vertical)).ConditionalTranspose(vertical)60 mainCrossSize.X = frenyard.Max(mainCrossSize.X, slot.MinBasis)61 return mainCrossSize62}63func (slot FlexboxSlot) fyGrowShrink() (int32, int32) {64 return slot.Grow, slot.Shrink65}66func (slot FlexboxSlot) fyCalcBasis(cross int32, vertical bool) int32 {67 if slot.Basis != 0 {68 return slot.Basis69 }70 return slot.fyMainCrossSizeForMainCrossLimits(frenyard.Vec2i{frenyard.SizeUnlimited, cross}, vertical, false).X71}72func (slot FlexboxSlot) fyGetOrder() int {73 return slot.Order74}75func (slot FlexboxSlot) fyRespectMinimumSize() bool {76 return slot.RespectMinimumSize77}78// -- Solver --79func fyFlexboxGetPreferredSize(details FlexboxContainer) frenyard.Vec2i {80 // Do note, this is in main/cross format.81 mainCrossSize := frenyard.Vec2i{}82 for _, v := range details.Slots {83 sz := v.fyMainCrossSizeForMainCrossLimits(frenyard.Vec2iUnlimited(), details.DirVertical, false)84 mainCrossSize.X += sz.X85 mainCrossSize.Y = frenyard.Max(mainCrossSize.Y, sz.Y)86 }87 return mainCrossSize.ConditionalTranspose(details.DirVertical)88}89type fyFlexboxRow struct {90 elem []fyFlexboxSlotlike91 area []frenyard.Area2i92 fullArea frenyard.Area2i93}94func (slot fyFlexboxRow) fyGrowShrink() (int32, int32) {95 return 1, 196}97// Critical to the whole thing and it's full of guesswork due to the vertical flags and axis juggling.98func (slot fyFlexboxRow) fyMainCrossSizeForMainCrossLimits(limits frenyard.Vec2i, vertical bool, debug bool) frenyard.Vec2i {99 if debug {100 fmt.Print("R{")101 }102 // Main & Cross in here refer to in the row flexbox, not the outer flexbox.103 maximumMain := int32(0)104 presentAreaCross := slot.fullArea.Size().ConditionalTranspose(vertical).Y105 for _, v := range slot.elem {106 lim := frenyard.Vec2i{X: limits.X, Y: presentAreaCross}107 if debug {108 fmt.Print(" ", limits.X, "x", presentAreaCross)109 }110 rcs := v.fyMainCrossSizeForMainCrossLimits(lim, vertical, false)111 maximumMain = frenyard.Max(maximumMain, rcs.X)112 if debug {113 fmt.Print(":", rcs.X, "x", rcs.Y)114 }115 }116 if debug {117 fmt.Print(" }")118 }119 return frenyard.Vec2i{X: maximumMain, Y: presentAreaCross}120}121func (slot fyFlexboxRow) fyCalcBasis(cross int32, vertical bool) int32 {122 return slot.fyMainCrossSizeForMainCrossLimits(frenyard.Vec2i{X: frenyard.SizeUnlimited, Y: cross}, vertical, false).X123}124func (slot fyFlexboxRow) fyGetOrder() int {125 return 0126}127func (slot fyFlexboxRow) fyRespectMinimumSize() bool {128 return false129}130// Do be aware, this only handles the one relevant axis.131func (slot *fyFlexboxRow) Fill(area frenyard.Area2i, vertical bool) {132 for k := range slot.area {133 if !vertical {134 // Rows perpendicular to X135 slot.area[k].X = area.X136 } else {137 // Rows perpendicular to Y138 slot.area[k].Y = area.Y139 }140 }141 slot.fullArea = area142}143type fyFlexboxSortingCollection struct {144 // The collection being sorted.145 slots []fyFlexboxSlotlike146 // Given a SOURCE slot index, what is the RESULTING slot index?147 originalToDisplayIndices []int148 // Given a RESULTING slot index, what is the SOURCE slot index?149 displayToOriginalIndices []int150}151func (sc fyFlexboxSortingCollection) Len() int {152 return len(sc.slots)153}154func (sc fyFlexboxSortingCollection) Less(i int, j int) bool {155 order1 := sc.slots[i].fyGetOrder()156 order2 := sc.slots[j].fyGetOrder()157 // Order1 != order2?158 if order1 < order2 {159 return true160 }161 if order1 > order2 {162 return false163 }164 // No, they're equal. Sort by original index.165 if sc.displayToOriginalIndices[i] < sc.displayToOriginalIndices[j] {166 return true167 }168 return false169}170func (sc fyFlexboxSortingCollection) Swap(i int, j int) {171 backup := sc.slots[i]172 backup2 := sc.originalToDisplayIndices[i]173 backup3 := sc.displayToOriginalIndices[i]174 sc.slots[i] = sc.slots[j]175 sc.originalToDisplayIndices[i] = sc.originalToDisplayIndices[j]176 sc.displayToOriginalIndices[i] = sc.displayToOriginalIndices[j]177 sc.slots[j] = backup178 sc.originalToDisplayIndices[j] = backup2179 sc.displayToOriginalIndices[j] = backup3180}181func fyFlexboxSolveLayout(details FlexboxContainer, limits frenyard.Vec2i) []frenyard.Area2i {182 // Stage 1. Element order pre-processing (DirReverse)183 slots := make([]fyFlexboxSlotlike, len(details.Slots))184 originalToDisplayIndices := make([]int, len(details.Slots))185 displayToOriginalIndices := make([]int, len(details.Slots))186 for k, v := range details.Slots {187 originalToDisplayIndices[k] = k188 displayToOriginalIndices[k] = k189 slots[k] = v190 }191 sort.Sort(fyFlexboxSortingCollection{192 slots: slots,193 originalToDisplayIndices: originalToDisplayIndices,194 displayToOriginalIndices: displayToOriginalIndices,195 })196 // Stage 2. Wrapping (if relevant)197 out := make([]frenyard.Area2i, len(slots))198 mainCrossLimits := limits.ConditionalTranspose(details.DirVertical)199 shouldWrap := fyFlexboxSolveLine(details, slots, out, mainCrossLimits, details.Debug)200 // One row, so this is simple201 rows := []fyFlexboxRow{{slots, out, frenyard.UnionArea2i(out)}}202 if shouldWrap && details.WrapMode != FlexboxWrapModeNone {203 // Wrapping has to start. Oh no...204 // Do note, lines is implicitly limited because of the "one slot cannot wrap" rule.205 lines := int32(2)206 for {207 rows = make([]fyFlexboxRow, lines)208 lineStartSlot := 0209 consumedSlots := 0210 currentLine := int32(0)211 for consumedSlots < len(slots) {212 // If it wraps...213 if fyFlexboxSolveLine(details, slots[lineStartSlot:consumedSlots+1], out[lineStartSlot:consumedSlots+1], mainCrossLimits, false) {214 // Revert it & finish the line.215 rows[currentLine] = fyFlexboxRow{216 slots[lineStartSlot:consumedSlots],217 out[lineStartSlot:consumedSlots],218 frenyard.UnionArea2i(out),219 }220 fyFlexboxSolveLine(details, rows[currentLine].elem, rows[currentLine].area, mainCrossLimits, false)221 // Now setup the new line.222 currentLine++223 lineStartSlot = consumedSlots224 if currentLine == lines {225 // Out of range, cancel before rows[currentLine] brings it to a halt226 break227 }228 // Retry the same slot (slot not consumed)229 } else {230 // Success! Advance.231 consumedSlots++232 }233 }234 if currentLine < lines {235 // Finish last line236 rows[currentLine] = fyFlexboxRow{237 slots[lineStartSlot:consumedSlots],238 out[lineStartSlot:consumedSlots],239 frenyard.UnionArea2i(out),240 }241 break242 }243 lines++244 }245 }246 if details.WrapMode != FlexboxWrapModeNone {247 // Stage 3. Row compression248 rowAreas := make([]frenyard.Area2i, len(rows))249 rowSlots := make([]fyFlexboxSlotlike, len(rows))250 for rk, row := range rows {251 rowSlots[rk] = row252 }253 fyFlexboxSolveLine(FlexboxContainer{254 DirVertical: !details.DirVertical,255 WrapMode: FlexboxWrapModeNone,256 }, rowSlots, rowAreas, frenyard.Vec2i{mainCrossLimits.Y, mainCrossLimits.X}, false)257 for rk, row := range rows {258 row.Fill(rowAreas[rk], !details.DirVertical)259 }260 } else {261 // Stage 3. Row setup262 if mainCrossLimits.Y != frenyard.SizeUnlimited {263 rows[0].Fill(frenyard.Area2iOfSize(mainCrossLimits.ConditionalTranspose(details.DirVertical)), !details.DirVertical)264 }265 }266 // Stage 4. Element order post-processing (DirReverse)267 realOutput := make([]frenyard.Area2i, len(out))268 for k, v := range originalToDisplayIndices {269 realOutput[k] = out[v]270 }271 return realOutput272}273// Returns true if should wrap. Will not return true ever for only one slot as this cannot wrap.274func fyFlexboxSolveLine(details FlexboxContainer, slots []fyFlexboxSlotlike, out []frenyard.Area2i, mainCrossLimits frenyard.Vec2i, debug bool) bool {275 if len(slots) == 0 {276 // Nowhere to output. Also, some calculations rely on at least one slot existing.277 return false278 }279 if debug {280 if details.DirVertical {281 fmt.Print("VERTICAL ")282 }283 fmt.Println("AREA", mainCrossLimits.X, "x", mainCrossLimits.Y)284 }285 // Substage 1. Input basis values & create total286 shares := make([]int32, len(slots))287 totalMainAccumulator := int32(0)288 totalGrowAccumulator := int32(0)289 totalShrinkAccumulator := int32(0)290 for idx, slot := range slots {291 shares[idx] = slot.fyCalcBasis(mainCrossLimits.Y, details.DirVertical)292 totalMainAccumulator += shares[idx]293 slotGrow, slotShrink := slot.fyGrowShrink()294 totalGrowAccumulator += slotGrow295 totalShrinkAccumulator += slotShrink296 }297 // Notably, totalMainAccumulator must not change after this point.298 // It's the 'reference' for if we ought to wrap.299 // Substage 2. Determine expansion or contraction300 if mainCrossLimits.X != frenyard.SizeUnlimited && totalMainAccumulator != mainCrossLimits.X {301 additionalSpaceAvailable := mainCrossLimits.X - totalMainAccumulator302 if debug {303 fmt.Println("COMPRESSOR II: ", additionalSpaceAvailable)304 }305 // Determine which accumulator to use.306 totalFactorAccumulator := totalGrowAccumulator307 if additionalSpaceAvailable < 0 {308 totalFactorAccumulator = totalShrinkAccumulator309 }310 // Actually redistribute space. This may require multiple passes as a factor may not always be fully appliable.311 // This is because the Flexbox system respects minimum size.312 // When set to true, the relevant factor must be subtracted from the Accumulator.313 slotsHitMinimumSize := make([]bool, len(slots))314 needAnotherPass := true315 for needAnotherPass && totalFactorAccumulator != 0 {316 needAnotherPass = false317 totalAlloc := int32(0)318 for idx, slot := range slots {319 if slotsHitMinimumSize[idx] {320 continue321 }322 grow, shrink := slot.fyGrowShrink()323 factor := grow324 smallestAlloc := -shares[idx] // Cannot shrink below 0325 largestAlloc := frenyard.SizeUnlimited326 // There is no 'largest alloc'; if the element is told to grow, that is what it will do327 if additionalSpaceAvailable < 0 {328 factor = shrink329 }330 if factor == 0 {331 // has no effect, and means totalFactorAccumulator could be 0332 continue333 }334 if additionalSpaceAvailable < 0 && shrink > 0 && slot.fyRespectMinimumSize() {335 // Smallest possible alloc: maximum amount that can be shrunk336 smallestAlloc = slot.fyMainCrossSizeForMainCrossLimits(frenyard.Vec2i{X: 0, Y: mainCrossLimits.Y}, details.DirVertical, false).X - shares[idx]337 }338 alloc := (additionalSpaceAvailable * factor) / totalFactorAccumulator339 // Limit allocation.340 clamped := false341 if alloc <= smallestAlloc {342 alloc = smallestAlloc343 clamped = true344 }345 if alloc >= largestAlloc {346 alloc = largestAlloc347 clamped = true348 }349 // If the limit is hit, remove from processing for the next loop.350 if clamped {351 slotsHitMinimumSize[idx] = true352 needAnotherPass = true353 totalFactorAccumulator -= factor354 }355 // Confirm allocation356 shares[idx] += alloc357 totalAlloc += alloc358 }359 additionalSpaceAvailable -= totalAlloc360 }361 // additionalSpaceAvailable non-zero: justify-content implementation goes here362 }363 // Substage 3. With horizontal sizes established, calculate crossLimit364 crossLimit := int32(0)365 for idx := 0; idx < len(slots); idx++ {366 crossLimit = frenyard.Max(crossLimit, slots[idx].fyMainCrossSizeForMainCrossLimits(frenyard.Vec2i{X: shares[idx], Y: mainCrossLimits.Y}, details.DirVertical, false).Y)367 }368 // -- Actual layout! For real this time! --369 mainPosition := int32(0)370 if debug {371 fmt.Println(" CROSS ", crossLimit)372 }373 for idx := 0; idx < len(slots); idx++ {374 out[idx] = frenyard.Area2iOfSize(frenyard.Vec2i{shares[idx], crossLimit}.ConditionalTranspose(details.DirVertical)).Translate(frenyard.Vec2i{mainPosition, 0}.ConditionalTranspose(details.DirVertical))375 if debug {376 fmt.Println(" SHARE ", shares[idx])377 }378 mainPosition += shares[idx]379 }380 if debug {381 fmt.Println("END AREA")382 }383 // If len(slots) <= 1 then wrapping would inf. loop, so only wrap for >1.384 return (len(slots) > 1) && (totalMainAccumulator > mainCrossLimits.X)385}386// -- UI element --387// UIFlexboxContainer lays out UILayoutElements using a partial implementation of Flexbox.388type UIFlexboxContainer struct {389 UIPanel390 UILayoutElementComponent391 _state FlexboxContainer392 _preferredSize frenyard.Vec2i393}394// NewUIFlexboxContainerPtr creates a UIFlexboxContainer from the FlexboxContainer details395func NewUIFlexboxContainerPtr(setup FlexboxContainer) *UIFlexboxContainer {396 container := &UIFlexboxContainer{397 UIPanel: NewPanel(frenyard.Vec2i{}),398 }399 InitUILayoutElementComponent(container)400 container.SetContent(setup)401 container.FyEResize(container._preferredSize)402 return container403}404// FyLSubelementChanged implements UILayoutElement.FyLSubelementChanged405func (ufc *UIFlexboxContainer) FyLSubelementChanged() {406 ufc._preferredSize = fyFlexboxGetPreferredSize(ufc._state)407 ufc.ThisUILayoutElementComponentDetails.ContentChanged()408}409// FyLSizeForLimits implements UILayoutElement.FyLSizeForLimits410func (ufc *UIFlexboxContainer) FyLSizeForLimits(limits frenyard.Vec2i) frenyard.Vec2i {411 if limits.Ge(ufc._preferredSize) {412 return ufc._preferredSize413 }414 solved := fyFlexboxSolveLayout(ufc._state, limits)415 max := frenyard.Vec2i{}416 for _, v := range solved {417 max = max.Max(v.Pos().Add(v.Size()))418 }419 return max420}421// SetContent changes the contents of the UIFlexboxContainer.422func (ufc *UIFlexboxContainer) SetContent(setup FlexboxContainer) {423 if ufc._state.Slots != nil {424 for _, v := range ufc._state.Slots {425 if v.Element != nil {426 ufc.ThisUILayoutElementComponentDetails.Detach(v.Element)427 }428 }429 }430 ufc._state = setup431 for _, v := range setup.Slots {432 if v.Element != nil {433 ufc.ThisUILayoutElementComponentDetails.Attach(v.Element)434 }435 }436 ufc.FyLSubelementChanged()437}438// FyEResize overrides UIPanel.FyEResize439func (ufc *UIFlexboxContainer) FyEResize(size frenyard.Vec2i) {440 ufc.UIPanel.FyEResize(size)441 areas := fyFlexboxSolveLayout(ufc._state, size)442 fixes := make([]PanelFixedElement, len(areas))443 fixesCount := 0444 for idx, slot := range ufc._state.Slots {445 if slot.Element != nil {446 fixes[fixesCount].Pos = areas[idx].Pos()447 fixes[fixesCount].Visible = true448 fixes[fixesCount].Element = slot.Element449 slot.Element.FyEResize(areas[idx].Size())450 fixesCount++451 }452 }453 ufc.ThisUIPanelDetails.SetContent(fixes[:fixesCount])454}...
uiLibScrollbox.go
Source:uiLibScrollbox.go
...7 * BEFORE CONTINUING: If you're here because of an "issue" where the scrollbox never activates the scrollbar,8 * keep in mind that you need to let your layout crush the scrollbox for the scrollbox to actually do anything.9 * 10 * HTML notes for reference:11 * The Flexbox design is so utterly amazing that to prevent it from just outright ignoring size constraints in favour of minimum sizes, you have to actually just outright. Try it in your browser if you don't believe me:12 * <html><head></head><body style="display: flex;"><div>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</div><div>BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB</div><div>CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC</div></body></html>13 * This is with, of course, the default flex-shrink: 1 value.14 * The "fix" is "min-width: 0;" on the element that you want to fix,15 * but the browser *refuses* to character-wrap unless given "overflow-wrap: break-word;" too.16 * Frenyard is somewhat less broken, and will by default implement this `min-width: 0;` technique.17 * but labels actually character-wrap by default if they need to.18 * 19 * Anyways!20 * Judging by the official Material Design website, it seems like it leaves OS scrollboxes alone.21 * This is as good an excuse as any to use the "NinePatch this and use our own judgement" technology...22 */23// ScrollbarValue represents the value a scrollbar alters.24type ScrollbarValue interface {25 FySValue() float6426 // Sets the value. It is the responsibility of the target to clamp these values; this will show attempts at overscrolling for potential feedback.27 FySSetValue(v float64)28}29// ScrollbarTheme represents the Frame pair that makes up a Scrollbar.30type ScrollbarTheme struct {31 // The Base covers the whole visible main axis. The bounds of this touches the cross-axis sides of the Movement.32 Base Frame33 // The Movement covers the part of the scrollbar that moves during scrolling. It is given only the padding as bounds.34 Movement Frame35}36// UIScrollbar is an implementation of a scrollbar.37type UIScrollbar struct {38 UIElementComponent39 UILayoutElementComponent40 LayoutElementNoSubelementsComponent41 _theme ScrollbarTheme42 Value ScrollbarValue43 MouseNotch float6444 _vertical bool45 _grabbed bool46}47// NewUIScrollbarPtr creates a new scrollbar with the given theme and direction.48func NewUIScrollbarPtr(theme ScrollbarTheme, vertical bool, value ScrollbarValue) *UIScrollbar {49 uis := &UIScrollbar{50 _theme: theme,51 _vertical: vertical,52 Value: value,53 MouseNotch: 0.1,54 }55 InitUILayoutElementComponent(uis)56 return uis57}58// FyETick implements UIElement.FyETick59func (uis *UIScrollbar) FyETick(time float64) {60}61func (uis *UIScrollbar) _calcMetrics() (insideArea frenyard.Area2i, movementSize frenyard.Vec2i, movementArea frenyard.Area2i) {62 insideArea = frenyard.Area2iOfSize(uis.FyESize()).Contract(uis._theme.Base.FyFPadding())63 movementSize = uis._theme.Movement.FyFPadding().Size()64 movementArea = insideArea.Align(movementSize, frenyard.Alignment2i{})65 return insideArea, movementSize, movementArea66}67// FyEDraw implements UIElement.FyEDraw68func (uis *UIScrollbar) FyEDraw(r frenyard.Renderer, under bool) {69 if under {70 uis._theme.Base.FyFDraw(r, uis.FyESize(), FramePassUnderBefore)71 } else {72 uis._theme.Base.FyFDraw(r, uis.FyESize(), FramePassOverBefore)73 }74 // start movement75 insideArea, movementSize, movementArea := uis._calcMetrics()76 // Ok, here comes the "fun part"...77 if uis._vertical {78 movementArea.Y.Pos = insideArea.Y.Pos + int32(float64(insideArea.Y.Size - movementArea.Y.Size) * uis.Value.FySValue())79 } else {80 movementArea.X.Pos = insideArea.X.Pos + int32(float64(insideArea.X.Size - movementArea.X.Size) * uis.Value.FySValue())81 }82 r.Translate(movementArea.Pos())83 if under {84 uis._theme.Movement.FyFDraw(r, movementSize, FramePassUnderBefore)85 uis._theme.Movement.FyFDraw(r, movementSize, FramePassUnderAfter)86 } else {87 uis._theme.Movement.FyFDraw(r, movementSize, FramePassOverBefore)88 uis._theme.Movement.FyFDraw(r, movementSize, FramePassOverAfter)89 }90 r.Translate(movementArea.Pos().Negate())91 // end movement92 if under {93 uis._theme.Base.FyFDraw(r, uis.FyESize(), FramePassUnderAfter)94 } else {95 uis._theme.Base.FyFDraw(r, uis.FyESize(), FramePassOverAfter)96 }97}98// FyENormalEvent implements UIElement.FyENormalEvent99func (uis *UIScrollbar) FyENormalEvent(me frenyard.NormalEvent) {100}101// FyEMouseEvent implements UIElement.FyEMouseEvent102func (uis *UIScrollbar) FyEMouseEvent(me frenyard.MouseEvent) {103 decreaser, increaser := frenyard.MouseButtonScrollLeft, frenyard.MouseButtonScrollRight104 if uis._vertical {105 decreaser, increaser = frenyard.MouseButtonScrollUp, frenyard.MouseButtonScrollDown106 }107 if me.ID == frenyard.MouseEventDown && me.Button == increaser {108 uis.Value.FySSetValue(uis.Value.FySValue() + uis.MouseNotch)109 } else if me.ID == frenyard.MouseEventDown && me.Button == decreaser {110 uis.Value.FySSetValue(uis.Value.FySValue() - uis.MouseNotch)111 } else if me.ID == frenyard.MouseEventDown && me.Button == frenyard.MouseButtonLeft {112 uis._grabbed = true113 } else if me.ID == frenyard.MouseEventUp && me.Button == frenyard.MouseButtonLeft {114 uis._grabbed = false115 }116 if uis._grabbed {117 insideArea, _, _ := uis._calcMetrics()118 insideAreaMain := insideArea.X119 if uis._vertical {120 insideAreaMain = insideArea.Y121 }122 pointerMain := me.Pos.ConditionalTranspose(uis._vertical).X123 uis.Value.FySSetValue(float64(pointerMain - insideAreaMain.Pos) / float64(insideAreaMain.Size))124 }125}126// FyLSizeForLimits implements UILayoutElement.FyLSizeForLimits127func (uis *UIScrollbar) FyLSizeForLimits(limits frenyard.Vec2i) frenyard.Vec2i {128 movementEffectiveSize := uis._theme.Movement.FyFPadding().Size()129 if uis._vertical {130 movementEffectiveSize.Y *= 2131 } else {132 movementEffectiveSize.X *= 2133 }134 return uis._theme.Base.FyFPadding().Size().Add(movementEffectiveSize)135}136// UIScrollbox allows scrolling around the contained element.137type UIScrollbox struct {138 UIPanel139 UILayoutElementComponent140 // The requirements for the scrollbar. Cached for simplicity's sake.141 _scrollbarMainCross frenyard.Vec2i142 _contained UILayoutElement143 _scrollbar *UIScrollbar144 // >0 means scrollbar is active145 _scrollLength int32146 _value float64147 _vertical bool148}149// NewUIScrollboxPtr creates a scrollbox.150func NewUIScrollboxPtr(theme ScrollbarTheme, content UILayoutElement, vertical bool) UILayoutElement {151 usc := &UIScrollbox{152 UIPanel: NewPanel(content.FyESize()),153 _contained: content,154 _vertical: vertical,155 }156 usc.ThisUIPanelDetails.Clipping = true157 usc._scrollbar = NewUIScrollbarPtr(theme, vertical, usc)158 InitUILayoutElementComponent(usc)159 usc.ThisUILayoutElementComponentDetails.Attach(usc._scrollbar)160 usc.ThisUILayoutElementComponentDetails.Attach(content)161 usc.FyEResize(usc.FyESize())162 return usc163}164// FyLSubelementChanged implements UILayoutElement.FyLSubelementChanged165func (usc *UIScrollbox) FyLSubelementChanged() {166 usc.ThisUILayoutElementComponentDetails.ContentChanged()167}168// FyLSizeForLimits implements UILayoutElement.FyLSizeForLimits169func (usc *UIScrollbox) FyLSizeForLimits(limits frenyard.Vec2i) frenyard.Vec2i {170 limitsMainCross := limits.ConditionalTranspose(usc._vertical)171 baseSize := usc._contained.FyLSizeForLimits(limits)172 if baseSize.ConditionalTranspose(usc._vertical).X > limitsMainCross.X {173 // scrollbar penalty174 limitsNormalWithBar := frenyard.Vec2i{frenyard.SizeUnlimited, frenyard.AddCU(limitsMainCross.Y, -usc._scrollbarMainCross.X)}.ConditionalTranspose(usc._vertical)175 baseSize = usc._contained.FyLSizeForLimits(limitsNormalWithBar)176 baseSizeMainCross := baseSize.ConditionalTranspose(usc._vertical)177 return frenyard.Vec2i{usc._scrollbarMainCross.X, baseSizeMainCross.Y + usc._scrollbarMainCross.Y}.ConditionalTranspose(usc._vertical)178 }179 return baseSize180}181// FyEMouseEvent overrides UIPanel.FyEMouseEvent182func (usc *UIScrollbox) FyEMouseEvent(me frenyard.MouseEvent) {183 acceptance := false184 if usc._scrollLength > 0 && (me.ID == frenyard.MouseEventDown || me.ID == frenyard.MouseEventUp) {185 acceptance = me.Button == frenyard.MouseButtonScrollLeft || me.Button == frenyard.MouseButtonScrollRight186 if usc._vertical {187 acceptance = me.Button == frenyard.MouseButtonScrollDown || me.Button == frenyard.MouseButtonScrollUp188 }189 }190 if acceptance {191 usc._scrollbar.FyEMouseEvent(me)192 } else {193 usc.UIPanel.FyEMouseEvent(me)194 }195}196// FyEResize overrides UIPanel.FyEResize197func (usc *UIScrollbox) FyEResize(size frenyard.Vec2i) {198 usc.UIPanel.FyEResize(size)199 usc._scrollbarMainCross = usc._scrollbar.FyLSizeForLimits(frenyard.Vec2i{}).ConditionalTranspose(usc._vertical)200 baseSize := usc._contained.FyLSizeForLimits(size)201 baseSizeMainCross := baseSize.ConditionalTranspose(usc._vertical)202 sizeMainCross := size.ConditionalTranspose(usc._vertical)203 if baseSizeMainCross.X > sizeMainCross.X {204 if baseSizeMainCross.X == frenyard.SizeUnlimited {205 fmt.Printf("frenyard/UIScrollbox: Scroll layout was given element that wanted literally infinite size. This can't be made to work; track it down and get rid of it: %v %v\n", usc, baseSize)206 }207 // Subtract scrollbar from size; this is used for both layout and for calculating scroll len.208 sizeWithoutScrollbar := frenyard.Vec2i{baseSizeMainCross.X, sizeMainCross.Y - usc._scrollbarMainCross.Y}.ConditionalTranspose(usc._vertical)209 // Recalculate with the adjusted constraints because of the removed scrollbar210 baseSizeMainCross = usc._contained.FyLSizeForLimits(sizeWithoutScrollbar).ConditionalTranspose(usc._vertical)211 sizeWithoutScrollbar = frenyard.Vec2i{baseSizeMainCross.X, sizeMainCross.Y - usc._scrollbarMainCross.Y}.ConditionalTranspose(usc._vertical)212 usc._scrollLength = baseSizeMainCross.X - sizeMainCross.X213 usc._scrollbar.MouseNotch = (float64(sizeMainCross.X) / 6) / float64(usc._scrollLength)214 // can haz scrollbar?215 usc._scrollbar.FyEResize(frenyard.Vec2i{sizeMainCross.X, usc._scrollbarMainCross.Y}.ConditionalTranspose(usc._vertical))216 usc._contained.FyEResize(sizeWithoutScrollbar)217 } else {218 usc._scrollLength = 0219 usc._contained.FyEResize(size)220 }221 usc._updatePositions()222}223func (usc *UIScrollbox) _updatePositions() {224 if usc._scrollLength > 0 {225 scrollPos := -int32(usc._value * float64(usc._scrollLength))226 sizeMainCross := usc.FyESize().ConditionalTranspose(usc._vertical)227 usc.ThisUIPanelDetails.SetContent([]PanelFixedElement{228 PanelFixedElement{229 Element: usc._contained,230 Pos: frenyard.Vec2i{scrollPos, 0}.ConditionalTranspose(usc._vertical),231 Visible: true,232 },233 PanelFixedElement{234 Element: usc._scrollbar,235 Pos: frenyard.Vec2i{0, sizeMainCross.Y - usc._scrollbarMainCross.Y}.ConditionalTranspose(usc._vertical),236 Visible: true,237 },238 })239 } else {240 usc.ThisUIPanelDetails.SetContent([]PanelFixedElement{241 PanelFixedElement{242 Element: usc._contained,243 Visible: true,244 },245 // This needs to exist so that the structure doesn't change, for focus reasons (searchboxes)246 PanelFixedElement{247 Element: usc._scrollbar,248 Pos: frenyard.Vec2i{},249 Visible: false,...
nosplit.go
Source:nosplit.go
...23#24# Lines beginning with # are comments.25#26# Each test case describes a sequence of functions, one per line.27# Each function definition is the function name, then the frame size,28# then optionally the keyword 'nosplit', then the body of the function.29# The body is assembly code, with some shorthands.30# The shorthand 'call x' stands for CALL x(SB).31# The shorthand 'callind' stands for 'CALL R0', where R0 is a register.32# Each test case must define a function named main, and it must be first.33# That is, a line beginning "main " indicates the start of a new test case.34# Within a stanza, ; can be used instead of \n to separate lines.35#36# After the function definition, the test case ends with an optional37# REJECT line, specifying the architectures on which the case should38# be rejected. "REJECT" without any architectures means reject on all architectures.39# The linker should accept the test case on systems not explicitly rejected.40#41# 64-bit systems do not attempt to execute test cases with frame sizes42# that are only 32-bit aligned.43# Ordinary function should work44main 045# Large frame marked nosplit is always wrong.46main 10000 nosplit47REJECT48# Calling a large frame is okay.49main 0 call big50big 1000051# But not if the frame is nosplit.52main 0 call big53big 10000 nosplit54REJECT55# Recursion is okay.56main 0 call main57# Recursive nosplit runs out of space.58main 0 nosplit call main59REJECT60# Chains of ordinary functions okay.61main 0 call f162f1 80 call f263f2 8064# Chains of nosplit must fit in the stack limit, 128 bytes.65main 0 call f166f1 80 nosplit call f267f2 80 nosplit68REJECT69# Larger chains.70main 0 call f171f1 16 call f272f2 16 call f373f3 16 call f474f4 16 call f575f5 16 call f676f6 16 call f777f7 16 call f878f8 16 call end79end 100080main 0 call f181f1 16 nosplit call f282f2 16 nosplit call f383f3 16 nosplit call f484f4 16 nosplit call f585f5 16 nosplit call f686f6 16 nosplit call f787f7 16 nosplit call f888f8 16 nosplit call end89end 100090REJECT91# Test cases near the 128-byte limit.92# Ordinary stack split frame is always okay.93main 11294main 11695main 12096main 12497main 12898main 13299main 136100# A nosplit leaf can use the whole 128-CallSize bytes available on entry.101# (CallSize is 32 on ppc64)102main 96 nosplit103main 100 nosplit; REJECT ppc64 ppc64le104main 104 nosplit; REJECT ppc64 ppc64le105main 108 nosplit; REJECT ppc64 ppc64le106main 112 nosplit; REJECT ppc64 ppc64le107main 116 nosplit; REJECT ppc64 ppc64le108main 120 nosplit; REJECT ppc64 ppc64le109main 124 nosplit; REJECT ppc64 ppc64le110main 128 nosplit; REJECT111main 132 nosplit; REJECT112main 136 nosplit; REJECT113# Calling a nosplit function from a nosplit function requires114# having room for the saved caller PC and the called frame.115# Because ARM doesn't save LR in the leaf, it gets an extra 4 bytes.116# Because arm64 doesn't save LR in the leaf, it gets an extra 8 bytes.117# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 fewer bytes than amd64.118main 96 nosplit call f; f 0 nosplit119main 100 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le120main 104 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le121main 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le122main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le123main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le124main 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64125main 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386126main 128 nosplit call f; f 0 nosplit; REJECT127main 132 nosplit call f; f 0 nosplit; REJECT128main 136 nosplit call f; f 0 nosplit; REJECT129# Calling a splitting function from a nosplit function requires130# having room for the saved caller PC of the call but also the131# saved caller PC for the call to morestack.132# RISC architectures differ in the same way as before.133main 96 nosplit call f; f 0 call f134main 100 nosplit call f; f 0 call f; REJECT ppc64 ppc64le135main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le136main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le137main 112 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64138main 116 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64139main 120 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386140main 124 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386141main 128 nosplit call f; f 0 call f; REJECT142main 132 nosplit call f; f 0 call f; REJECT143main 136 nosplit call f; f 0 call f; REJECT144# Indirect calls are assumed to be splitting functions.145main 96 nosplit callind146main 100 nosplit callind; REJECT ppc64 ppc64le147main 104 nosplit callind; REJECT ppc64 ppc64le148main 108 nosplit callind; REJECT ppc64 ppc64le149main 112 nosplit callind; REJECT ppc64 ppc64le amd64150main 116 nosplit callind; REJECT ppc64 ppc64le amd64151main 120 nosplit callind; REJECT ppc64 ppc64le amd64 386152main 124 nosplit callind; REJECT ppc64 ppc64le amd64 386153main 128 nosplit callind; REJECT154main 132 nosplit callind; REJECT155main 136 nosplit callind; REJECT156# Issue 7623157main 0 call f; f 112158main 0 call f; f 116159main 0 call f; f 120160main 0 call f; f 124161main 0 call f; f 128162main 0 call f; f 132163main 0 call f; f 136164`165var (166 commentRE = regexp.MustCompile(`(?m)^#.*`)167 rejectRE = regexp.MustCompile(`(?s)\A(.+?)((\n|; *)REJECT(.*))?\z`)168 lineRE = regexp.MustCompile(`(\w+) (\d+)( nosplit)?(.*)`)169 callRE = regexp.MustCompile(`\bcall (\w+)\b`)170 callindRE = regexp.MustCompile(`\bcallind\b`)171)172func main() {173 goarch := os.Getenv("GOARCH")174 if goarch == "" {175 goarch = runtime.GOARCH176 }177 version, err := exec.Command("go", "tool", "compile", "-V").Output()178 if err != nil {179 bug()180 fmt.Printf("running go tool compile -V: %v\n", err)181 return182 }183 if strings.Contains(string(version), "framepointer") {184 // Skip this test if GOEXPERIMENT=framepointer185 return186 }187 dir, err := ioutil.TempDir("", "go-test-nosplit")188 if err != nil {189 bug()190 fmt.Printf("creating temp dir: %v\n", err)191 return192 }193 defer os.RemoveAll(dir)194 tests = strings.Replace(tests, "\t", " ", -1)195 tests = commentRE.ReplaceAllString(tests, "")196 nok := 0197 nfail := 0198TestCases:199 for len(tests) > 0 {200 var stanza string201 i := strings.Index(tests, "\nmain ")202 if i < 0 {203 stanza, tests = tests, ""204 } else {205 stanza, tests = tests[:i], tests[i+1:]206 }207 m := rejectRE.FindStringSubmatch(stanza)208 if m == nil {209 bug()210 fmt.Printf("invalid stanza:\n\t%s\n", indent(stanza))211 continue212 }213 lines := strings.TrimSpace(m[1])214 reject := false215 if m[2] != "" {216 if strings.TrimSpace(m[4]) == "" {217 reject = true218 } else {219 for _, rej := range strings.Fields(m[4]) {220 if rej == goarch {221 reject = true222 }223 }224 }225 }226 if lines == "" && !reject {227 continue228 }229 var gobuf bytes.Buffer230 fmt.Fprintf(&gobuf, "package main\n")231 var buf bytes.Buffer232 ptrSize := 4233 switch goarch {234 case "mips64", "mips64le":235 ptrSize = 8236 fmt.Fprintf(&buf, "#define CALL JAL\n#define REGISTER (R0)\n")237 case "ppc64", "ppc64le":238 ptrSize = 8239 fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (CTR)\n")240 case "arm":241 fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")242 case "arm64":243 ptrSize = 8244 fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")245 case "amd64":246 ptrSize = 8247 fmt.Fprintf(&buf, "#define REGISTER AX\n")248 case "s390x":249 ptrSize = 8250 fmt.Fprintf(&buf, "#define REGISTER R10\n")251 default:252 fmt.Fprintf(&buf, "#define REGISTER AX\n")253 }254 for _, line := range strings.Split(lines, "\n") {255 line = strings.TrimSpace(line)256 if line == "" {257 continue258 }259 for i, subline := range strings.Split(line, ";") {260 subline = strings.TrimSpace(subline)261 if subline == "" {262 continue263 }264 m := lineRE.FindStringSubmatch(subline)265 if m == nil {266 bug()267 fmt.Printf("invalid function line: %s\n", subline)268 continue TestCases269 }270 name := m[1]271 size, _ := strconv.Atoi(m[2])272 // The limit was originally 128 but is now 592.273 // Instead of rewriting the test cases above, adjust274 // the first stack frame to use up the extra bytes.275 if i == 0 {276 size += 592 - 128277 // Noopt builds have a larger stackguard.278 // See ../cmd/dist/buildruntime.go:stackGuardMultiplier279 for _, s := range strings.Split(os.Getenv("GO_GCFLAGS"), " ") {280 if s == "-N" {281 size += 720282 }283 }284 }285 if size%ptrSize == 4 || goarch == "arm64" && size != 0 && (size+8)%16 != 0 {286 continue TestCases287 }288 nosplit := m[3]289 body := m[4]290 if nosplit != "" {291 nosplit = ",7"292 } else {293 nosplit = ",0"294 }295 body = callRE.ReplaceAllString(body, "CALL ·$1(SB);")296 body = callindRE.ReplaceAllString(body, "CALL REGISTER;")297 fmt.Fprintf(&gobuf, "func %s()\n", name)298 fmt.Fprintf(&buf, "TEXT ·%s(SB)%s,$%d-0\n\t%s\n\tRET\n\n", name, nosplit, size, body)299 }300 }301 if err := ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666); err != nil {302 log.Fatal(err)303 }304 if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), gobuf.Bytes(), 0666); err != nil {305 log.Fatal(err)306 }307 cmd := exec.Command("go", "build")308 cmd.Dir = dir309 output, err := cmd.CombinedOutput()310 if err == nil {311 nok++312 if reject {...
size
Using AI Code Generation
1import "fmt"2type square struct {3}4func (s square) size() float64 {5}6func main() {7s := square{10}8fmt.Println(s.size())9}
size
Using AI Code Generation
1import (2func main() {3 fmt.Println("Size of int is", size(1))4 fmt.Println("Size of int8 is", size(int8(1)))5 fmt.Println("Size of int16 is", size(int16(1)))6 fmt.Println("Size of int32 is", size(int32(1)))7 fmt.Println("Size of int64 is", size(int64(1)))8 fmt.Println("Size of uint is", size(uint(1)))9 fmt.Println("Size of uint8 is", size(uint8(1)))10 fmt.Println("Size of uint16 is", size(uint16(1)))11 fmt.Println("Size of uint32 is", size(uint32(1)))12 fmt.Println("Size of uint64 is", size(uint64(1)))13 fmt.Println("Size of uintptr is", size(uintptr(1)))14 fmt.Println("Size of float32 is", size(float32(1)))15 fmt.Println("Size of float64 is", size(float64(1)))16 fmt.Println("Size of complex64 is", size(complex64(1)))17 fmt.Println("Size of complex128 is", size(complex128(1)))18 fmt.Println("Size of byte is", size(byte(1)))19 fmt.Println("Size of rune is", size(rune(1)))20 fmt.Println("Size of string is", size("Hello World"))21}
size
Using AI Code Generation
1import "fmt"2type size struct {3}4func main() {5 s := size{10, 5}6 fmt.Println("Area is", s.area())7 fmt.Println("Perimeter is", s.perimeter())8}9func (s size) area() int {10}11func (s size) perimeter() int {12 return 2 * (s.length + s.width)13}14import "fmt"15type size struct {16}17func main() {18 s := size{10, 5}19 fmt.Println("Area is", s.area())20 fmt.Println("Perimeter is", s.perimeter())21}22func (s *size) area() int {23}24func (s *size) perimeter() int {25 return 2 * (s.length + s.width)26}27import "fmt"28type size struct {29}30func main() {31 s := &size{10, 5}32 fmt.Println("Area is", s.area())33 fmt.Println("Perimeter is", s.perimeter())34}35func (s *size) area() int {36}37func (s *size) perimeter() int {38 return 2 * (s.length + s.width
size
Using AI Code Generation
1import "fmt"2func main() {3 var a = []int{1, 2, 3, 4, 5}4 fmt.Println(a)5 fmt.Println("Size of array is ", len(a))6}
size
Using AI Code Generation
1import "fmt"2func main() {3 fmt.Println("size of a is", unsafe.Sizeof(a))4 fmt.Println("size of b is", unsafe.Sizeof(b))5 fmt.Println("size of c is", unsafe.Sizeof(c))6 fmt.Println("size of d is", unsafe.Sizeof(d))7}8import "fmt"9func main() {10 fmt.Println("size of a is", unsafe.Sizeof(a))11 fmt.Println("size of b is", unsafe.Sizeof(b))12 fmt.Println("size of c is", unsafe.Sizeof(c))13 fmt.Println("size of d is", unsafe.Sizeof(d))14}15import "fmt"16func main() {17 fmt.Println("size of a is", unsafe.Sizeof(a))18 fmt.Println("size of b is", unsafe.Sizeof(b))19 fmt.Println("size of c is", unsafe.Sizeof(c))20 fmt.Println("size of d is", unsafe.Sizeof(d))21}22import "fmt"23func main() {24 fmt.Println("size of a is", unsafe.Sizeof(a))
size
Using AI Code Generation
1import (2func main() {3 fmt.Println("area of s1 is:", s1.area())4}5import (6func main() {7 fmt.Println("area of s1 is:", s1.area())8}9import (10func main() {11 fmt.Println("area of s1 is:", s1.area())12}13import (14func main() {15 fmt.Println("area of s1 is:", s1.area())16}17import (18func main() {19 fmt.Println("area of s1 is:", s1.area())20}21import (22func main() {23 fmt.Println("area of s1 is:", s1.area())24}25import (26func main() {27 fmt.Println("area of s1 is:", s1.area())28}29import (30func main() {
size
Using AI Code Generation
1import (2func main() {3 s := size{}4 s.size()5}6import (7func main() {8 s := size{}9 s.size()10}11import (12func main() {13 s := size{}14 s.size()15}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!