Ooops
November 25, 2020, 05:30:37 AM

Author Topic: [bmx] Vertical Tab Strip by N [ 1+ years ago ]  (Read 675 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Vertical Tab Strip by N [ 1+ years ago ]
« on: June 29, 2017, 12:28:38 AM »
Title : Vertical Tab Strip
Author : N
Posted : 1+ years ago

Description : A product of boredom.  Basically, this is a row of vertical tabs.  Maybe they're buttons.  Who knows?  I certainly don't!

To use/run this, you'll need to grab <a href="codearcs04e6.html?code=2567" >Animating Fields[/url] and <a href="codearcsdc9b.html?code=2494" >Color Class[/url].  The latter is just determining whether light or dark text is better suited for a particular tab.

<a href="http://screencast.com/t/M2M5YmUxMmEt" target="_blank">[img]www.spifftastic.net/skitch/video-20100111-145246.html">[/url]

This was mostly made just so I could mess around with the animation code I wrote a while back.  Over the course of a few hours I've just been fiddling with adding bits and pieces to it - the test code probably equates to a castle of beach balls built atop a rickety bridge, but the tabstrip itself is pretty solid, I think.


Code :
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Import "color.bmx"
  4. Import "animation.bmx"
  5.  
  6. Function WithinRect:Int(px!, py!, rx!, ry!, rw!, rh!)
  7.         Return (px >= rx And py >= ry And px < rx+rw And py < ry+rh)
  8. End Function
  9.  
  10. Type Tab
  11.         Field name$                             ' Read-write before addition to tabstrip, read-only after
  12.         Field color:TColor
  13.        
  14.         ' Private
  15.         Field _alpha!
  16.         Field _index:Int
  17.        
  18.         Method Init:Tab(name$, red%=-1, green%=-1, blue%=-1)
  19.                 If red > -1 And green > -1 And blue > -1 Then
  20.                         color.InitWithIntComponents(red, green, blue, 255)
  21.                 EndIf
  22.                 Self.name = name
  23.                 Return Self
  24.         End Method
  25.        
  26.         Method New()
  27.                 color = New TColor.InitWithHSV(Rnd(360!), Rnd(0.8!, 1!), Rnd(0.8!, 1!))
  28.         End Method
  29. End Type
  30.  
  31. Type TabStrip
  32.         Field x!=0, y!=0                                ' read-write
  33.         Field width!=12                                 ' read-only
  34.         Field selected:Tab = Null               ' read-only
  35.        
  36.         'Private
  37.         Field tabs:TList = New TList
  38.         Field clickedIndex:Int = -1             ' index of the tab clicked on - used for handling mouse up/down events
  39.        
  40.         Field backr!=32, backg!=32, backb!=32   ' background color
  41.        
  42.         Method Height:Int()
  43.                 Return tabs.Count()*24
  44.         End Method
  45.        
  46.         Method Render()
  47.                 Const th% = 24
  48.                
  49.                 Local last:Int = tabs.Count()
  50.                
  51.                 SetHandle(0,0)
  52.                 SetScale(1,1)
  53.                 SetRotation(0)
  54.                
  55.                 SetAlpha(1)
  56.                 SetLineWidth(2)
  57.                 SetBlend(ALPHABLEND)
  58.                
  59.                 ' Outline
  60.                
  61.                 SetColor(0,0,0)
  62.                 For Local t:Tab = EachIn tabs
  63.                         If t.name = "" Then Continue
  64.                         Local ty! = y+t._index*24
  65.                         Local tw! = width + 18*t._alpha
  66.                         DrawOval(x+tw-11.5, ty-2, 24, th+4)
  67.                         DrawRect(x,ty-2,tw+2,28)
  68.                 Next
  69.                
  70.                 ' End Outline
  71.                
  72.                 If selected Then
  73.                         SetColor(backr, backg, backb)
  74.                         DrawRect(x, y, 12, last*24)
  75.                 EndIf
  76.                
  77.                 Local tx! = x
  78.                 If selected then
  79.                         tx :+ 12
  80.                 EndIf
  81.                
  82.                 For Local t:Tab = EachIn tabs
  83.                         If t.name = "" Then Continue
  84.                         Local ty! = y+t._index*24
  85.                         Local tw! = width + 18*t._alpha
  86.                        
  87.                         If t = selected Then
  88.                                 SetColor(backr, backg, backb)
  89.                         Else
  90.                                 Local tt!=32*(1!-t._alpha)
  91.                                 SetColor(backr*t._alpha+tt, backg*t._alpha+tt, backb*t._alpha+tt)
  92.                         EndIf
  93.                        
  94.                         If selected Then
  95.                                 tw :- 12
  96.                         EndIf
  97.                        
  98.                         DrawOval(tx+tw-10, ty, 20, th)
  99.                         DrawRect(tx, ty, tw, th)
  100.                        
  101.                         If t = selected Then
  102.                                 Local h!, v!
  103.                                 h = t.color.GetHue()
  104.                                 v = t.color.GetValue()
  105.                                 If 25.5 < h And h < 203.5 And .7 < v Then
  106.                                         SetColor(32, 32, 32)
  107.                                 Else
  108.                                         SetColor(255,255,255)
  109.                                 EndIf
  110.                         Else
  111.                                 SetColor(255,255,255)
  112.                         EndIf
  113.                        
  114.                         DrawText(t.name, Floor(tx+8+12*(selected=Null)+9*t._alpha + .5), Floor(ty + 12 - TextHeight(t.name)*.5 + .5))
  115.                 Next
  116.                
  117.                 ' Odd little 'dings'
  118.                 If selected And selected._alpha < 0.9995! Then ' 0.9995 = arbitrary cutoff
  119.                         SetLineWidth(6)
  120.                         Local d! = selected._alpha
  121.                         Local tx! = x + width + 9*d + 6
  122.                         Local ty! = y + selected._index*24 + 8
  123.                         SetBlend(ALPHABLEND)
  124.                         Local s!=Sin(180*d)
  125.                         SetAlpha(s)
  126.                         Local r%,g%,b%,_%
  127.                         selected.color.IntComponents(r,g,b,_)
  128.                         SetColor(r,g,b)
  129.                         DrawLine(tx + 40*d, ty, tx+8+40*d, ty, False)
  130.                         DrawLine(tx + 24*d, ty+8+13*d, tx+9+24*d, ty+12+13*d, False)
  131.                         DrawLine(tx + 24*d, ty-8-13*d, tx+9+24*d, ty-12-13*d, False)
  132.                 EndIf
  133.                 ' End dings
  134.         End Method
  135.        
  136.         Method AddTab(t:Tab)
  137.                 If t = Null Then Return
  138.                 t._index = tabs.Count()
  139.                 t._alpha = 0
  140.                 tabs.AddLast(t)
  141.                 width = Max(TextWidth(t.name)+28, width)
  142.         End Method
  143.        
  144.         ' For a separator tab, pass an empty string
  145.         Method AddTabWithName(name$)
  146.                 AddTab(New Tab.Init(name))
  147.         End Method
  148.        
  149.         Method SelectTab(index%)
  150.                 If selected And selected._index = index Then
  151.                         Return
  152.                 EndIf
  153.                
  154.                 Local newsel:Tab
  155.                 If index >= 0 And index < tabs.Count() Then
  156.                         newsel = Tab(tabs.ValueAtIndex(index))
  157.                         If newsel.name = "" Then
  158.                                 ' Selecting a separator tab = noop
  159.                                 Return
  160.                         EndIf
  161.                 EndIf
  162.                
  163.                 If selected Then
  164.                         Animate(selected, "_alpha", 0, 270)
  165.                 EndIf
  166.                
  167.                 If newsel = Null Then
  168.                         selected = Null
  169.                         Animate(Self, "backr", 32, 100)
  170.                         Animate(Self, "backg", 32, 100)
  171.                         Animate(Self, "backb", 32, 100)
  172.                         Return
  173.                 Else
  174.                         selected = newsel
  175.                         Animate(selected, "_alpha", 1, 270)
  176.                         Local r%,g%,b%,_%
  177.                         selected.color.IntComponents(r,g,b,_)
  178.                         Animate(Self, "backr", r, 100)
  179.                         Animate(Self, "backg", g, 100)
  180.                         Animate(Self, "backb", b, 100)
  181.                 EndIf
  182.         End Method
  183.        
  184.         Method HandleEvent:Int(event:TEvent)
  185.                 Local mx#, my#
  186.                 GetOrigin(mx,my)
  187.                 mx :+ event.x
  188.                 my :+ event.y
  189.                
  190.                 Select event.id
  191.                         Case EVENT_MOUSEDOWN
  192.                                 If event.data <> 1 Or Not WithinRect(mx, my, x+12, y, width, 24*tabs.Count()) Then
  193.                                         Return False
  194.                                 EndIf
  195.                                 clickedIndex = (my - Int(y)) / 24
  196.                                 Return True
  197.                                
  198.                         Case EVENT_MOUSEUP
  199.                                 If clickedIndex = -1 Then
  200.                                         Return False
  201.                                 EndIf
  202.                                
  203.                                 If WithinRect(mx, my, x+12, y+24*clickedIndex, width-12, 25) Then
  204.                                         SelectTab(clickedIndex)
  205.                                 EndIf
  206.                                
  207.                                 clickedIndex = -1
  208.                                
  209.                                 Return True
  210.                 End Select
  211.                
  212.                 Return False
  213.         End Method
  214. End Type
  215.  
  216.  
  217.  
  218.  
  219.  
  220. ' TESTO PRESTO
  221. ' THIS IS JUST UGLY, UGLY CODE
  222.  
  223. 'buildopt:gui
  224.  
  225. Graphics 800,600,0
  226.  
  227. ' You can grab this font at http://android.git.kernel.org/?p=platform/frameworks/base.git;a=tree;f=data/fonts;hb=HEAD
  228. Local font:TImageFont = LoadImageFont("DroidSans.ttf",12)
  229. Local qfont:TImageFont = LoadImageFont("DroidSans-Bold.ttf",28*(Double(GraphicsWidth())/800))
  230.  
  231. Local loadGameTab:Tab = New Tab.Init("Load Game", 255, 109, 0)
  232. Local quitGameTab:Tab = New Tab.Init("Quit", 65, 148, 239)
  233.  
  234. Local ts:TabStrip = New TabStrip
  235. ts.AddTab(New Tab.Init("New Game", 219, 0, 147))
  236. ts.AddTab(loadGameTab)
  237. ts.AddTab(New Tab.Init("Options", 221, 32, 32))
  238. ts.AddTab(New Tab.Init("Achievements", 159, 79, 238))
  239. ts.AddTab(New Tab.Init("", 221, 32, 32))
  240. ts.AddTab(New Tab.Init("Credits", 150, 230, 57))
  241. ts.AddTab(quitGameTab)
  242.  
  243. Local toogies:TabStrip = New TabStrip
  244. For Local i:Int = 1 To 8
  245.         toogies.AddTabWithName("Game #"+i)
  246. Next
  247.  
  248.  
  249. Local CenterX! = GraphicsWidth()*.5
  250. If qfont Then
  251.         SetImageFont(qfont)
  252.         CenterX = Min(CenterX, GraphicsWidth()*.7-TextWidth("This doesn't actually quit!")*.8)
  253. Else
  254.         CenterX = Min(CenterX, GraphicsWidth()*.7-TextWidth("This doesn't actually quit!")*1.8)
  255. EndIf
  256.  
  257. ts.x = Floor(CenterX-ts.width*.5)
  258. ts.y = (GraphicsHeight()-ts.Height())*.5
  259. toogies.x = Floor(CenterX-ts.width-toogies.width)
  260. toogies.y = (GraphicsHeight()-toogies.Height())*.5
  261.  
  262. SetClsColor(80,80,80)
  263.  
  264. Local running:Int = True
  265.  
  266. SetBlend(ALPHABLEND)
  267. Local poly#[] = [12#, 0#, 0#, 0#, 0#, Float GraphicsHeight(), 12#, Float GraphicsHeight()]
  268. Local a!=GraphicsWidth()
  269. Local lastSelected:Tab = Null
  270.  
  271.  
  272. Function SinInterp!(s!,f!,t!)
  273.         Return s+Sin(t*115)*((f-s)*1.09369221296335!)
  274. End Function
  275.  
  276. Local rotoff!=Rnd(0,22)
  277.  
  278. While running
  279.         While PollEvent()
  280.                 If Not (ts.HandleEvent(CurrentEvent) Or (ts.selected = loadGameTab And loadGameTab._alpha > .99999 And toogies.HandleEvent(CurrentEvent))) And (CurrentEvent.id = EVENT_APPTERMINATE Or (CurrentEvent.id = EVENT_KEYDOWN And CurrentEvent.data = KEY_ESCAPE)) Then
  281.                         running = False
  282.                 endIf
  283.         Wend
  284.        
  285.         If ts.selected <> lastSelected Then
  286.                 rotoff!=Rnd(0,22)
  287.         EndIf
  288.        
  289.         If ts.selected = loadGameTab And lastSelected <> loadGameTab Then
  290.                 Animate(toogies, "x", Floor(CenterX-toogies.width*.5), 230, SinInterp)
  291.                 Animate(ts, "x", Floor(CenterX-toogies.width*2.5), 100)
  292.         ElseIf lastSelected = loadGameTab And ts.selected <> loadGameTab
  293.                 toogies.SelectTab(-1)
  294.                 Animate(toogies, "x", Floor(CenterX-ts.width-toogies.width), 200)
  295.                 Animate(ts, "x", Floor(CenterX-ts.width*.5), 230, SinInterp)
  296.         EndIf
  297.         lastSelected = ts.selected
  298.        
  299.         Animation.UpdateAnimations
  300.        
  301.         SetClsColor(ts.backr*.25, ts.backg*.25, ts.backb*.25)
  302.        
  303.         Cls
  304.        
  305.         If font Then SetImageFont(font)
  306.        
  307.         ' Fancy background
  308.        
  309.         SetBlend(ALPHABLEND)
  310.        
  311.         SetAlpha(.02)
  312.         SetLineWidth(3)
  313.         Local odd%=False
  314.         For Local i:Int = 0 Until 100 Step 2
  315.                 SetBlend(ALPHABLEND)
  316.                 odd=~odd
  317.                 If odd Then
  318.                         SetColor(ts.backr, ts.backg, ts.backb)
  319.                 Else
  320.                         SetColor(ts.backr*1.8, ts.backg*1.8, ts.backb*1.8)
  321.                 EndIf
  322.                 SetAlpha(.02)
  323.                 Local d! = 1.0 - Double(i)/100
  324.                 poly[2] = (200+a+100*(1.0-d))*d
  325.                 poly[4] = a*d
  326.                 DrawPoly(poly)
  327.                 SetBlend(LIGHTBLEND)
  328.                 SetColor(ts.backr*1.5, ts.backg*1.5, ts.backb*1.5)
  329.                 SetAlpha(.25)
  330.                 DrawLine(poly[2],poly[3], poly[4],poly[5])
  331.                 i :+ Int(9*d)
  332.         Next
  333.        
  334.         ' Toogies!
  335.        
  336.         SetViewport(ts.x, 0, GraphicsWidth()-ts.x, GraphicsHeight())
  337.        
  338.         SetBlend(ALPHABLEND)
  339.         SetAlpha(1)
  340.         SetColor(0,0,0)
  341.         DrawRect(toogies.x+12, 0, 2, GraphicsHeight())
  342.        
  343.         ' End toogies background
  344.        
  345.         toogies.Render
  346.        
  347.         ' Bit more background
  348.        
  349.         If ts.x < toogies.x Then
  350.                 SetColor(toogies.backr, toogies.backg, toogies.backb)
  351.                 SetBlend(ALPHABLEND)
  352.                 SetAlpha(.7)
  353.                 DrawRect(ts.x, 0, toogies.x-ts.x+12, GraphicsHeight())
  354.                 SetAlpha(1)
  355.                 DrawRect(toogies.x, 0, 12, GraphicsHeight())
  356.         EndIf
  357.        
  358.        
  359.         SetBlend(ALPHABLEND)
  360.         SetAlpha(1)
  361.         SetColor(0,0,0)
  362.         DrawRect(ts.x+12, 0, 2, GraphicsHeight())
  363.        
  364.         SetViewport(0, 0, GraphicsWidth(), GraphicsHeight())
  365.        
  366.         ' End fancy/toogies background
  367.        
  368.         ts.Render
  369.        
  370.         ' Yet more background
  371.        
  372.         SetColor(ts.backr, ts.backg, ts.backb)
  373.         SetBlend(ALPHABLEND)
  374.         SetAlpha(.7)
  375.         DrawRect(0, 0, ts.x+12, GraphicsHeight())
  376.         SetAlpha(1)
  377.         DrawRect(ts.x, 0, 12, GraphicsHeight())
  378.        
  379.         ' Ok now we're really done
  380.        
  381.         ' Text!
  382.         If ts.selected And ts.selected <> loadGameTab Then
  383.                 If qfont Then
  384.                         SetImageFont(qfont)
  385.                 Else
  386.                         SetImageFont(Null)
  387.                 EndIf
  388.                 Local txt$
  389.                 Select ts.selected.name
  390.                         Case "New Game" txt = "Yeah, right"
  391.                         Case "Options" txt = "You have none"
  392.                         Case "Achievements" txt = "You've achieved nothing"
  393.                         Case "Credits" txt = "Noel Cower"
  394.                         Case "Quit" txt = "This doesn't actually quit!"
  395.                 End Select
  396.                 SetColor(255,255,255)
  397.                 SetAlpha(ts.selected._alpha)
  398.                 SetHandle(TextWidth(txt)*.5, TextHeight(txt)*.5)
  399.                 Local angle!=360*Sin(ts.selected._alpha*105) + rotoff
  400.                 SetRotation(angle)
  401.                 Local s!=ts.selected._alpha
  402.                 If Not qfont Then
  403.                         s :* 1.75
  404.                 EndIf
  405.                 SetScale(s,s)
  406.                 DrawText(txt, GraphicsWidth()*.7, GraphicsHeight()*.5)
  407.                 SetRotation(0)
  408.                 SetScale(1,1)
  409.                 SetHandle(0,0)
  410.         EndIf
  411.         ' End text!
  412.        
  413.         Flip
  414. Wend


Comments :


Zeke(Posted 1+ years ago)

 this is quite good example.. i like it.


GW(Posted 1+ years ago)

 pretty sharp. thumbs up!


N(Posted 1+ years ago)

 Tweaked it a tiny bit - decided to round the X/Y coords when drawing the tab names so they don't end up looking funky thanks to filtering.  Also made things move a little more in the test code, but otherwise it's the same.


 

SimplePortal 2.3.6 © 2008-2014, SimplePortal