Give your ButtonGadgets some FLAIR! Code included [WINDOWS]
Posted: Sun Jul 22, 2012 7:14 am
Are you TIRED of boring buttons in your programs? Me too! Now feel free to make them look very tasty, and behave like they always do!
I was so proud of my little library I had to share it. Granted, my web-developer I work with did it very quickly with has damn CSS, but hey... Now PB apps can be classy too. Let me know if anyone finds it useful!
Here is the code to the include file: "jelly-button.pb"
I was so proud of my little library I had to share it. Granted, my web-developer I work with did it very quickly with has damn CSS, but hey... Now PB apps can be classy too. Let me know if anyone finds it useful!
Here is the code to the include file: "jelly-button.pb"
Code: Select all
; Jelly Button Library by Justin Jack
; Use as you please
; This library will add a nice Jelly-Like coating to your buttons. They will still act identical to PureBasic buttons.
; User Functions:
;
;
; ** Add_Some_Jelly( gadget_number, jelly_color )....Adds a nice bit of jelly to your button.
;
; gadget_number = the PB gadget number of your button
; jelly_color = the normal-state RGB color of your button.
; ** Spread_Jelly( gadget_number, iNewColor = -1 )...Changes the color of your Jelly.
;
; gadget_number = the PB gadget number of your button
; iNewColor = the new normal-state RGB color of your button.
;
; Remarks: Spread-Jelly will cause the button to re-draw the cached "Jelly" images, so it will update size as well
; but the jBtn_WndProc() catches this anyway through WM_WINDOWPOSCHANGED
; ** Remove_Jelly( gadget_number )...Removes the Jelly and turns it back to a normal button
;
; gadget_number = the PB gadget number of your button
; ** Get_Jelly_Color( gadget_number )...Gets the current Jelly color of the button
;
; gadget_number = the PB gadget number of your button
; ** Set_Jelly_Text_Color( gadget_number, iColor )...Changes the text color on the button.
; gadget_number = the PB gadget number of your button
; iColor = the new RGB color of the text on the button
;
; Remarks: To change the button FONT, just treat it like any other PB control use SetGadgetFont()
; ** Set_Jelly_Shadow_Color( gadget_number, iColor )
; gadget_number = the PB gadget number of your button
; iColor = the new RGB color of the text on the button
;
Structure JBTN_INFO
blbdPending.b
bButtonState.b
bHiLiteTimerActive.b
iHiLiteTimer.i
iClickReleaseTimer.i
bClickTimerActive.b
imgRegular.i
imgHilite.i
imgPressed.i
hDcReg.i
hDcPressed.i
hDcHiLite.i
hOldBmpReg.i
hOldBmpPressed.i
hOldBmpHiLite.i
iActiveFont.i
iFrontColor.i
iShadowColor.i
szJellyText.s
EndStructure
Structure JELLY_BUTTON_INFO
numGadget.i
hGadget.i
hParent.i
iParentBkColor.i
jelly_color.i
*lpJBtnInfo.JBTN_INFO
*lpOldWndProc
bJustLeft.b
EndStructure
Global NewList jelly_buttons.JELLY_BUTTON_INFO()
Procedure Make_Jelly_Images( iJellyColor.i, bkColor.i, cx, cy, *lpJellyImages.JBTN_INFO )
jelly_color = iJellyColor
jelly_color = RGBA(Red(jelly_color), Green(jelly_color), Blue(jelly_color), $FF)
btn_size.SIZE\cx = cx
btn_size\cy = cy
If IsImage(*lpJellyImages\imgHilite)
FreeImage(*lpJellyImages\imgHilite)
EndIf
If IsImage(*lpJellyImages\imgPressed)
FreeImage(*lpJellyImages\imgPressed)
EndIf
If IsImage(*lpJellyImages\imgRegular)
FreeImage(*lpJellyImages\imgRegular)
EndIf
*lpJellyImages\imgRegular.i = CreateImage(#PB_Any, btn_size\cx, btn_size\cy, 32)
*lpJellyImages\imgHilite = CreateImage(#PB_Any, btn_size\cx, btn_size\cy, 32)
*lpJellyImages\imgPressed = CreateImage(#PB_Any, btn_size\cx, btn_size\cy, 32)
For i = 0 To 2
Select i
Case 0
this_image = *lpJellyImages\imgRegular.i
Case 1
this_image = *lpJellyImages\imgHilite
Case 2
this_image = *lpJellyImages\imgPressed
EndSelect
StartDrawing(ImageOutput(this_image))
Box(0, 0, cx, cy, bkColor)
DrawingMode(#PB_2DDrawing_AlphaBlend)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4, jelly_color)
If i = 1
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4, RGBA($FF, $FF, $FF, $50))
ElseIf i = 2
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4, RGBA($00, $00, $00, $70))
EndIf
DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend)
BackColor(RGBA(0, 0, 0, 130))
FrontColor(RGBA(0, 0, 0, 00))
LinearGradient(-10, 0, (btn_size\cx / 3), 0)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
FrontColor(RGBA(0, 0, 0, 130))
BackColor(RGBA(0, 0, 0, 00))
LinearGradient(btn_size\cx - (btn_size\cx / 3), 0, (btn_size\cx + 10), 0)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
If i = 2
FrontColor(RGBA($FF, $FF, $FF, 150))
BackColor(RGBA($FF, $FF, $FF, 00))
LinearGradient(0, btn_size\cy / 3, 0, btn_size\cy)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
Else
FrontColor(RGBA($FF, $FF, $FF, 00))
BackColor(RGBA($FF, $FF, $FF, 150))
LinearGradient(0, 0, 0, (btn_size\cy / 3) * 2)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4)
EndIf
DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
RoundBox(0, 0, btn_size\cx, btn_size\cy, 4, 4, RGBA($A0, $A0, $A0, $FF))
StopDrawing()
Next
EndProcedure
Procedure Spread_Jelly( gadget_number, iNewColor = -1 )
jelly_found = #False
ForEach jelly_buttons()
If jelly_buttons()\numGadget = gadget_number
If iNewColor = -1
iNewColor = jelly_buttons()\jelly_color
EndIf
jelly_buttons()\jelly_color = iNewColor
Make_Jelly_Images(iNewColor, jelly_buttons()\iParentBkColor, GadgetWidth(gadget_number), GadgetHeight(gadget_number), jelly_buttons()\lpJBtnInfo)
With jelly_buttons()\lpJBtnInfo
SelectObject_(\hDcReg, ImageID(\imgRegular))
SelectObject_(\hDcHiLite, ImageID(\imgHilite))
SelectObject_(\hDcPressed, ImageID(\imgPressed))
EndWith
InvalidateRect_(jelly_buttons()\hGadget, 0, 0)
EndIf
Next
EndProcedure
Procedure jBtn_WndProc( hWnd, uMsg, wParam, lParam )
ForEach jelly_buttons()
If jelly_buttons()\hGadget = hWnd
*lpji.JELLY_BUTTON_INFO = @jelly_buttons()
Break
EndIf
Next
Select uMsg
Case #WM_SETFONT
*lpji\lpJBtnInfo\iActiveFont = wParam
InvalidateRect_(hWnd, 0, 0)
Case #WM_TIMER
Select wParam
Case 124
If GetAsyncKeyState_(#VK_LBUTTON) & $8000 <> $8000
KillTimer_(hWnd, 124)
*lpji\lpJBtnInfo\bClickTimerActive = #False
InvalidateRect_(hWnd, 0, 1)
EndIf
Case 123
GetCursorPos_(@myCursorPos.POINT)
ScreenToClient_(*lpji\hParent, @myCursorPos)
okToStop = #False
If myCursorPos\x <= GadgetX(*lpji\numGadget) Or myCursorPos\x >= GadgetX(*lpji\numGadget) + GadgetWidth(*lpji\numGadget)
okToStop = #True
EndIf
If myCursorPos\y <= GadgetY(*lpji\numGadget) Or myCursorPos\y >= GadgetY(*lpji\numGadget) + GadgetHeight(*lpji\numGadget)
okToStop = #True
EndIf
If okToStop = #True
KillTimer_(hWnd, 123)
*lpji\lpJBtnInfo\bHiLiteTimerActive = #False
InvalidateRect_(hWnd, 0, 1)
EndIf
EndSelect
Case #WM_WINDOWPOSCHANGED
Spread_Jelly(*lpji\numGadget)
Case #WM_MOUSEMOVE
GetCursorPos_(@myCursorPos.POINT)
ScreenToClient_(*lpji\hParent, @myCursorPos)
in_jelly_rect = #True
If myCursorPos\x < GadgetX(*lpji\numGadget) Or myCursorPos\x > GadgetX(*lpji\numGadget) + GadgetWidth(*lpji\numGadget)
in_jelly_rect = #False
EndIf
If myCursorPos\y < GadgetY(*lpji\numGadget) Or myCursorPos\y > GadgetY(*lpji\numGadget) + GadgetHeight(*lpji\numGadget)
in_jelly_rect = #False
EndIf
If in_jelly_rect = #True
If Not(*lpji\lpJBtnInfo\bHiLiteTimerActive)
*lpji\lpJBtnInfo\bHiLiteTimerActive = #True
SetTimer_(hWnd, 123, 50, #Null)
InvalidateRect_(hWnd, 0, 1)
EndIf
*lpji\bJustLeft = #True
Else
If *lpji\bJustLeft = #True
*lpji\bJustLeft = #False
InvalidateRect_(hWnd, 0, 0)
EndIf
EndIf
Case #WM_SETTEXT
*lpji\lpJBtnInfo\szJellyText = PeekS(lParam)
InvalidateRect_(hWnd, 0, 0)
ProcedureReturn 1
Case #WM_LBUTTONDOWN
If Not(*lpji\lpJBtnInfo\bClickTimerActive)
*lpji\lpJBtnInfo\bClickTimerActive = #True
SetTimer_(hWnd, 124, 50, #Null)
*lpji\lpJBtnInfo\blbdPending = #True
InvalidateRect_(hWnd, 0, 1)
EndIf
Case #WM_PAINT
cx = GadgetWidth(*lpji\numGadget)
cy = GadgetHeight(*lpji\numGadget)
xofset = 0
yofset = 0
in_jelly_rect = #True
GetCursorPos_(@myCursorPos.POINT)
ScreenToClient_(*lpji\hParent, @myCursorPos)
If myCursorPos\x < GadgetX(*lpji\numGadget) Or myCursorPos\x > GadgetX(*lpji\numGadget) + GadgetWidth(*lpji\numGadget)
in_jelly_rect = #False
EndIf
If myCursorPos\y < GadgetY(*lpji\numGadget) Or myCursorPos\y > GadgetY(*lpji\numGadget) + GadgetHeight(*lpji\numGadget)
in_jelly_rect = #False
EndIf
If (*lpji\lpJBtnInfo\bClickTimerActive And in_jelly_rect = #True)
hdc_to_use = *lpji\lpJBtnInfo\hDcPressed
xofset = 1
yofset = 1
ElseIf *lpji\lpJBtnInfo\bHiLiteTimerActive
hdc_to_use = *lpji\lpJBtnInfo\hDcHiLite
Else
hdc_to_use = *lpji\lpJBtnInfo\hDcReg
EndIf
BeginPaint_(hWnd, @ps.PAINTSTRUCT)
BitBlt_(ps\hdc, 0, 0, cx, cy, hdc_to_use, 0, 0, #SRCCOPY)
mText.s = *lpji\lpJBtnInfo\szJellyText
mTextLen = Len(mText)
SelectObject_(ps\hdc, *lpji\lpJBtnInfo\iActiveFont)
GetTextExtentPoint32_(ps\hdc, @mText, mTextLen, @gep.SIZE)
SetBkMode_(ps\hdc, #TRANSPARENT)
SetTextColor_(ps\hdc, *lpji\lpJBtnInfo\iShadowColor)
gRect.RECT\left = 1 + xofset
gRect\top = (((cy / 2) - (gep\cy / 2)) + 1) + yofset
gRect\right = cx + 1 + xofset
gRect\bottom = (cy / 2) + gep\cy + 1 + yofset
DrawText_(ps\hdc, @mText, mTextLen, @gRect, #DT_CENTER)
SetTextColor_(ps\hdc, *lpji\lpJBtnInfo\iFrontColor)
gRect.RECT\left = xofset
gRect\top = ((cy / 2) - (gep\cy / 2)) + yofset
gRect\right = cx + xofset
gRect\bottom = (cy / 2 ) + gep\cy + yofset
DrawText_(ps\hdc, @mText, mTextLen, @gRect, #DT_CENTER)
EndPaint_(hWnd, @ps)
ProcedureReturn #True
Case #WM_ERASEBKGND
ProcedureReturn #True
EndSelect
ProcedureReturn CallWindowProc_(*lpji\lpOldWndProc, hWnd, uMsg, wParam, lParam)
EndProcedure
Procedure is_jelly_button( gadget_number )
retVal = #False
If Not(IsGadget(gadget_number))
ProcedureReturn retVal
EndIf
ForEach jelly_buttons()
If jelly_buttons()\numGadget = gadget_number
retVal = #True
Break
EndIf
Next
ProcedureReturn retVal
EndProcedure
Procedure Get_Jelly_Color( gadget_number )
retVal = #False
If Not(IsGadget(gadget_number))
ProcedureReturn retVal
EndIf
ForEach jelly_buttons()
If jelly_buttons()\numGadget = gadget_number
retVal = jelly_buttons()\jelly_color
Break
EndIf
Next
ProcedureReturn retVal
EndProcedure
Procedure Set_Jelly_Text_Color( gadget_number, iColor )
ForEach jelly_buttons()
If jelly_buttons()\numGadget = gadget_number
jelly_buttons()\lpJBtnInfo\iFrontColor = iColor
InvalidateRect_(jelly_buttons()\hGadget, 0, 0)
Break
EndIf
Next
EndProcedure
Procedure Set_Jelly_Shadow_Color( gadget_number, iColor )
ForEach jelly_buttons()
If jelly_buttons()\numGadget = gadget_number
jelly_buttons()\lpJBtnInfo\iShadowColor = iColor
InvalidateRect_(jelly_buttons()\hGadget, 0, 0)
Break
EndIf
Next
EndProcedure
Procedure Remove_Jelly( gadget_number )
ResetList(jelly_buttons())
While NextElement(jelly_buttons())
If jelly_buttons()\numGadget = gadget_number
SetWindowLongPtr_(jelly_buttons()\hGadget, #GWLP_WNDPROC, jelly_buttons()\lpOldWndProc)
With jelly_buttons()\lpJBtnInfo
SelectObject_(\hDcHiLite, \hOldBmpHiLite)
SelectObject_(\hDcPressed, \hOldBmpPressed)
SelectObject_(\hDcReg, \hOldBmpReg)
DeleteDC_(\hDcHiLite)
DeleteDC_(\hDcPressed)
DeleteDC_(\hDcReg)
If IsImage(\imgHilite)
FreeImage(\imgHilite)
EndIf
If IsImage(\imgPressed)
FreeImage(\imgPressed)
EndIf
If IsImage(\imgRegular)
FreeImage(\imgRegular)
EndIf
EndWith
cText.s = jelly_buttons()\lpJBtnInfo\szJellyText
SetWindowLongPtr_(jelly_buttons()\hGadget, #GWL_STYLE, GetWindowLongPtr_(jelly_buttons()\hGadget, #GWL_STYLE) ! #BS_OWNERDRAW)
SetWindowPos_(jelly_buttons()\hGadget, #Null, 0, 0, 0, 0, #SWP_NOZORDER|#SWP_NOSIZE|#SWP_NOMOVE)
FreeMemory(jelly_buttons()\lpJBtnInfo)
DeleteElement(jelly_buttons())
If IsGadget(gadget_number)
SetGadgetText(gadget_number, cText)
InvalidateRect_(GadgetID(gadget_number), 0, 0)
EndIf
Break
EndIf
Wend
EndProcedure
Procedure Add_Some_Jelly( gadget_number, jelly_color )
If Not(IsGadget(gadget_number))
ProcedureReturn 0
EndIf
okToCreateJelly = #True
ResetList(jelly_buttons())
While NextElement(jelly_buttons())
If Not(IsGadget(jelly_buttons()\numGadget)) Or Not(IsWindow_(jelly_buttons()\hGadget))
DeleteElement(jelly_buttons())
EndIf
If jelly_buttons()\numGadget = gadget_number And jelly_buttons()\hGadget = GadgetID(gadget_number)
okToCreateJelly = #False
Break
EndIf
Wend
If okToCreateJelly
AddElement(jelly_buttons())
jelly_buttons()\hGadget = GadgetID(gadget_number)
jelly_buttons()\numGadget = gadget_number
jelly_buttons()\lpJBtnInfo = AllocateMemory(SizeOf(JBTN_INFO))
jelly_buttons()\hParent = GetParent_(jelly_buttons()\hGadget)
hTempDC = GetDC_(jelly_buttons()\hParent)
jelly_buttons()\iParentBkColor = GetPixel_(hTempDC, GadgetX(gadget_number)-1, GadgetY(gadget_number))
ReleaseDC_(jelly_buttons()\hParent, hTempDC)
jelly_buttons()\jelly_color = jelly_color
Make_Jelly_Images(jelly_color, jelly_buttons()\iParentBkColor, GadgetWidth(gadget_number), GadgetHeight(gadget_number), jelly_buttons()\lpJBtnInfo)
If Not(IsImage(jelly_buttons()\lpJBtnInfo\imgRegular))
Debug "imgRegular is bad!"
CancelOut = #True
EndIf
If Not(IsImage(jelly_buttons()\lpJBtnInfo\imgPressed))
Debug "imgPressed is bad!"
CancelOut = #True
EndIf
If Not(IsImage(jelly_buttons()\lpJBtnInfo\imgHilite))
Debug "Hi lite image is bad!"
CancelOut = #True
EndIf
If CancelOut = #True
If IsImage(jelly_buttons()\lpJBtnInfo\imgRegular)
FreeImage(jelly_buttons()\lpJBtnInfo\imgRegular)
EndIf
If IsImage(jelly_buttons()\lpJBtnInfo\imgPressed)
FreeImage(jelly_buttons()\lpJBtnInfo\imgPressed)
EndIf
If IsImage(jelly_buttons()\lpJBtnInfo\imgHilite)
FreeImage(jelly_buttons()\lpJBtnInfo\imgHilite)
EndIf
FreeMemory(jelly_buttons()\lpJBtnInfo)
DeleteElement(jelly_buttons())
ProcedureReturn 0
EndIf
jelly_buttons()\lpOldWndProc = GetWindowLongPtr_(jelly_buttons()\hGadget, #GWLP_WNDPROC)
jelly_buttons()\lpJBtnInfo\iActiveFont = SendMessage_(jelly_buttons()\hGadget, #WM_GETFONT, 0, 0)
hGenDC = GetDC_(#Null)
jelly_buttons()\lpJBtnInfo\hDcHiLite = CreateCompatibleDC_(hGenDC)
jelly_buttons()\lpJBtnInfo\hDcPressed = CreateCompatibleDC_(hGenDC)
jelly_buttons()\lpJBtnInfo\hDcReg = CreateCompatibleDC_(hGenDC)
SetWindowLongPtr_(jelly_buttons()\hGadget, #GWL_STYLE, GetWindowLongPtr_(jelly_buttons()\hGadget, #GWL_STYLE) | #BS_OWNERDRAW)
SetWindowPos_(jelly_buttons()\hGadget, #Null, 0, 0, 0, 0, #SWP_NOZORDER|#SWP_NOSIZE|#SWP_NOMOVE)
With jelly_buttons()\lpJBtnInfo
\hOldBmpHiLite = SelectObject_(\hDcHiLite, ImageID(jelly_buttons()\lpJBtnInfo\imgHilite))
\hOldBmpReg = SelectObject_(\hDcReg, ImageID(jelly_buttons()\lpJBtnInfo\imgRegular))
\hOldBmpPressed= SelectObject_(\hDcPressed, ImageID(jelly_buttons()\lpJBtnInfo\imgPressed))
\szJellyText = GetGadgetText(jelly_buttons()\numGadget)
EndWith
SetWindowLongPtr_(jelly_buttons()\hGadget, #GWLP_WNDPROC, @jBtn_WndProc())
ReleaseDC_(#Null, hGenDC)
ProcedureReturn 1
Else
ProcedureReturn 0
EndIf
EndProcedure