Jump to content

GUI Skinning...


Recommended Posts

The zip, attached below, contains 6 .bmp's and my example script. There are 3 pictures for each type (up arrow, down arrow), normal, mouse over, and mouse down.

It works fine except for one tiny thing that bothers me...

Note the normal image, move your mouse over and it will turn red, then click and hold and you will see it turn red/black. Release the mouse and the image will turn inverted and red. It turns red because your mouse is over it.

Now heres the problem...

After following the above steps, without moving your mouse off the image *important*, click again. You will notice that the image does not turn red/black when mouse down, and stays red. And if you continoue to click, without moving your mouse off, it will be red each time but with the image inverted.

I have tried and tried but I can't seem to make the image turn red/black if you click and don't move mouse mouse of the image.

You can get the desired effect I want by clicking, moving your mouse off the image, moving it back on and clicking, then repeating.

Please download the attached zip and see my script. Its not large and I just can't seem to figure out the sequence or right commands to get the desired effect.

Thanks.

Edited by Burrup

qq

Link to comment
Share on other sites

Find the diff. (works for me now)

#include <GUIConstants.au3>

Global $aR[8], $U = 1

$aR[2] = "RU.bmp"
$aR[3] = "RUO.bmp"
$aR[4] = "RUC.bmp"
$aR[5] = "RD.bmp"
$aR[6] = "RDO.bmp"
$aR[7] = "RDC.bmp"

$main_gui = GUICreate("Test", 265, 264, -1, -1, $WS_POPUPWINDOW)

$test = GUICtrlCreatePic("RU.bmp",100, 100, 15, 15)

GUISetState(@SW_SHOW)

While 1
   $CursorInfo = GUIGetCursorInfo()
   $msg = GUIGetMsg()
   While $CursorInfo[4] = $test AND $CursorInfo[2]
      Sleep(5)
      $CursorInfo = GUIGetCursorInfo()
      If $CursorInfo[2] = 0 AND $CursorInfo[4] = $test Then 
         If $U = 1 Then
            GUICtrlSetImage($test, $aR[6])
            $U = 2
         ElseIf $U = 2 Then
            GUICtrlSetImage($test, $aR[3])
            $U = 1
         EndIf
      EndIf
   Wend
   If $U = 1 Then
      _MouseOver($test, $aR[2], $aR[3], $aR[4], $aR)
   ElseIf $U = 2 Then
      _MouseOver($test, $aR[5], $aR[6], $aR[7], $aR)
   EndIf
WEnd

Func _MouseOver(ByRef $ControlID, $pic1, $pic2, $pic3, ByRef $array)
   $CursorInfo = GUIGetCursorInfo()
   If $CursorInfo[2] And $CursorInfo[4] = $ControlID Then
      If $array[1] = 0 Then GUICtrlSetImage($ControlID, $pic3)
      $array[1] = 1
   Else
      $array[1] = 0
   EndIf
   If $CursorInfo[4] = $ControlID Then
      If $array[0] = 0 Then GUICtrlSetImage($ControlID, $pic2)
      $array[0] = 1
   Else
      If $array[0] = 1 Then GUICtrlSetImage($ControlID, $pic1)
      $array[0] = 0
      $array[1] = 0
   EndIf
EndFunc

Your Array[1] value was always "1" if you clicked until you moved your mouse out of the pic

Done very nice btw, one func for your whole GUI pic changing behaviour

Edited by TuMbLeWeEd
Link to comment
Share on other sites

To actually make a good program " GUI SKIN" with lots of Functionality like "BUTTONS/PICS" and the accompanying processes (ifs)

Does'nt this "Mouse-Over" process use alot of the systems resouces???

Processor... etc

Just a question...

Thx

8)

Edited by Valuater

NEWHeader1.png

Link to comment
Share on other sites

@TuMbLeWeEd

Yeah I like to be resourceful for functions. For my actual script I'm skinning 3 buttons, min, roll and close.

Each has there own array. Index 0 and 1 contain the values to determine what state. And if there are more then 3 pics, like my above exmaple script, extra index's are added containing the location of the new pictures :(.

Thanks for the help. I knew I was close and I posted this right before I went to bed, when I was in bed I thought to myself, "It can't be that hard", and thought it might be the array values.

Thanks again.

@Valuater

Yes it does a little bit. I'm actaully calling GUIGetMsg() and GUIGetCursorInfo() 2x. I can't test no but I think I can minimize the CPU usage.

@Anyone

I'm also looking for a way to change this...

While $CursorInfo[4] = $test AND $CursorInfo[2]
      Sleep(5)
      $CursorInfo = GUIGetCursorInfo()
      If $CursorInfo[2] = 0 AND $CursorInfo[4] = $test Then 
         If $U = 1 Then
            GUICtrlSetImage($test, $aR[6])
            $U = 2
         ElseIf $U = 2 Then
            GUICtrlSetImage($test, $aR[3])
            $U = 1
         EndIf
      EndIf
Wend

Helge provided me with that and it works great except because it enters the loop it stops the rest of the script working while you hold your mouse down on an image. When GUIGetCursorInfo() is returned the 3rd index (2) contains if the mouse was clicked. Unlike GUIGetMsg(), GUIGetCursorInfo() will be 1 when you mouse down and will continue to be 1 until you release the mouse. Because of this and the delay with using both GUIGetMsg() and GUIGetCursorInfo() in an If Statement such as...

If $msg = $GUI_EVENT_PRIMARYUP And $CursorInfo[4] = $test

Is why I have to use the above method of the loop. But I am quite confident another work around can be implemented use If Statements are no loop.

Thanks again.

qq

Link to comment
Share on other sites

Improved my code a bit :

(Edit : Made it clearer by adding color to label)

#include <GUIConstants.au3>

Dim $clickStatus = 0

GUICreate("",100,100)
$cLabel = GUICtrlCreateLabel("Click me...",20,20,60,60,$SS_SUNKEN)
GUICtrlSetBkColor($cLabel,0x0)
GUICtrlSetColor($cLabel,0xffffff)

GUISetState ()

While 1
    $msg = GUIGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop

    $curInfo = GUIGetCursorInfo()
    
; If mouse-button is pressed down over label..
    If $curInfo[4] = $cLabel AND $curInfo[2] AND NOT $clickStatus Then
        $clickStatus = 1
        GUICtrlSetBkColor($cLabel,0x000099)
    EndIf
        
; If mouse-button has been pressed down, and is moved outside label..
    If NOT $curInfo[4] AND $clickStatus Then
        $clickStatus = 0
        GUICtrlSetBkColor($cLabel,0x0)
    EndIf
    
; Checks if mouse-button is released while over label..
    If $clickStatus AND $curInfo[4] = $cLabel AND NOT $curInfo[2] Then ExitLoop
  
Wend
Edited by Helge
Link to comment
Share on other sites

@TuMbLeWeEd

Yeah I like to be resourceful for functions. For my actual script I'm skinning 3 buttons, min, roll and close.

Each has there own array. Index 0 and 1 contain the values to determine what state. And if there are more then 3 pics, like my above exmaple script, extra index's are added containing the location of the new pictures :(.

Thanks for the help. I knew I was close and I posted this right before I went to bed, when I was in bed I thought to myself, "It can't be that hard", and thought it might be the array values.

Thanks again.

@Valuater

Yes it does a little bit. I'm actaully calling GUIGetMsg() and GUIGetCursorInfo() 2x. I can't test no but I think I can minimize the CPU usage.

@Anyone

I'm also looking for a way to change this...

While $CursorInfo[4] = $test AND $CursorInfo[2]
      Sleep(5)
      $CursorInfo = GUIGetCursorInfo()
      If $CursorInfo[2] = 0 AND $CursorInfo[4] = $test Then 
         If $U = 1 Then
            GUICtrlSetImage($test, $aR[6])
            $U = 2
         ElseIf $U = 2 Then
            GUICtrlSetImage($test, $aR[3])
            $U = 1
         EndIf
      EndIf
Wend

Helge provided me with that and it works great except because it enters the loop it stops the rest of the script working while you hold your mouse down on an image. When GUIGetCursorInfo() is returned the 3rd index (2) contains if the mouse was clicked. Unlike GUIGetMsg(), GUIGetCursorInfo() will be 1 when you mouse down and will continue to be 1 until you release the mouse. Because of this and the delay with using both GUIGetMsg() and GUIGetCursorInfo() in an If Statement such as...

If $msg = $GUI_EVENT_PRIMARYUP And $CursorInfo[4] = $test

Is why I have to use the above method of the loop. But I am quite confident another work around can be implemented use If Statements are no loop.

Thanks again.

<{POST_SNAPBACK}>

Changed it all, much simpler if you have more controls.

#include <GUIConstants.au3>

Global $aR[11], $U = 1

$aR[0] = 0;button identifier
$aR[1] = 0;mousedown done
$aR[2] = 0;mouseover done
$aR[3] = "RU.bmp"
$aR[4] = "RUO.bmp"
$aR[5] = "RUC.bmp"
$aR[6] = "RD.bmp"
$aR[7] = "RDO.bmp"
$aR[8] = "RDC.bmp"
$aR[9] = "EventTest0";event 1 function
$aR[10] = "EventTest1";event 2 function

$main_gui = GUICreate("Test", 265, 264, -1, -1, $WS_POPUPWINDOW)

$test = GUICtrlCreatePic("RU.bmp",100, 100, 15, 15)

GUISetState(@SW_SHOW)

While 1
    $msg = GUIGetMsg()
    _GetMsg($msg)
    $CursorInfo = GUIGetCursorInfo($main_gui)
    ConsoleWrite("ControlID: " & $CursorInfo[4] & @LF)
    If $CursorInfo[4] = $test Then
        _MouseOver($test, $aR)
    EndIf
    
WEnd

Func _GetMsg($gui_msg)
;normal gui message handling (if needed)
EndFunc 

Func EventTest0()
    msgbox(0,"test","arrow up click event")
EndFunc

Func EventTest1()
    msgbox(0,"test","arrow down click event")
EndFunc

Func _MouseOver($ControlID, ByRef $array)
    Local $CursorInf,$gui_msg,$mousedown = 0
;loop until the controlID is diff (until mouse is out of focussed pic)
    Do
        $CursorInf = GUIGetCursorInfo()
        If Not $CursorInf[2] then;mouse not down
            if $array[0]=0 and $array[2] = 0 then
                GUICtrlSetImage($test, $array[4])
                $array[2] = 1
                $array[1] = 0
            Elseif $array[0]=1 and $array[2] = 0 Then
                GUICtrlSetImage($test, $array[7])
                $array[2] = 1
                $array[1] = 0
            EndIf
        ;this wil cause the mouse up event
        ;change the images first and launch the event function
            if $mousedown = 1 then
                $mousedown = 0
                if $array[0]=0 Then
                    GUICtrlSetImage($test, $array[7])
                    $array[0] = 1
                    Call($array[9])
                Else
                    GUICtrlSetImage($test, $array[4])
                    $array[0]= 0
                    Call($array[10])
                EndIf
            EndIf
        ElseIf $CursorInf[2] then;mouse down
            if $array[0]=0 and $array[1] = 0 then
                GUICtrlSetImage($test, $array[5])
            ;$array[0] = 1
                $array[1] = 1
            Elseif $array[0]=1 and $array[1] = 0 Then
                GUICtrlSetImage($test, $array[8])
            ;$array[0] = 0
                $array[1] = 1
            EndIf
            $array[2] = 0
            $mousedown = 1
        EndIf
    ;you still want the gui to respond when the mouse is over a control
        $gui_msg = GUIGetMsg()
        _GetMsg($gui_msg)
    Until $CursorInf[4] <> $ControlID
;set the none mouseover pics
    if $array[0]=0 then
        GUICtrlSetImage($test, $array[3])
    Else
        GUICtrlSetImage($test, $array[6])
    EndIf
    $array[2] = 0
EndFunc

EDIT: made some changes and included an event launcher

Edited by TuMbLeWeEd
Link to comment
Share on other sites

I've ended up using this...

Func _MouseOver(ByRef $ControlID, $pic1, $pic2, $pic3, ByRef $array)
   If $CursorInfo[2] And $CursorInfo[4] = $ControlID Then
      If $array[1] = 0 Then GUICtrlSetImage($ControlID, $pic3)
      $array[1] = 1
      $array[2] = 1
   Else
      $array[1] = 0
   EndIf
   If $CursorInfo[4] = $ControlID Then
      If $array[0] = 0 Then GUICtrlSetImage($ControlID, $pic2)
      $array[0] = 1
   Else
      If $array[0] = 1 Then GUICtrlSetImage($ControlID, $pic1)
      $array[0] = 0
      $array[1] = 0
      $array[2] = 0
   EndIf
EndFunc

Because I'm skinning multiple buttons, all bar 1 use 3 pictures. The one I provided everyone one with is the exception. To determine whether its up or down I'm using...

If $Up = 1 Then
   _MouseOver($test, $aR[3], $aR[4], $aR[5], $aR)
ElseIf $Up = 2 Then
   _MouseOver($test, $aR[6], $aR[7], $aR[8], $aR)
EndIf

@TuMbLeWeEd

Before you posted I had changed the array to have 9 elements, just like you did. I had 2 functions but now I have combined them in one, _MouseOver().

I think I might changed the name of it and submit it in 'Scripts and Scraps'. Any idea's?

qq

Link to comment
Share on other sites

Just try this one, beginning of a skinning UDF

#include <GUIConstants.au3>
Global $GUISkinnnedSkinArray[1]

$main_gui = GUICreate("Test", 265, 264, -1, -1, $WS_POPUPWINDOW)

$test0 = _GUISkinnedCtrlCreateButton("RU.bmp|RUO.bmp|RUC.bmp|RD.bmp|RDO.bmp|RDC.bmp|EventTest0|EventTest1",100, 100, 15, 15,True)
$test1 = _GUISkinnedCtrlCreateButton("RU.bmp|RUO.bmp|RUC.bmp|EventTest2",115, 100, 15, 15)
$test2 = _GUISkinnedCtrlCreateButton("RD.bmp|RDO.bmp|RDC.bmp|RU.bmp|RUO.bmp|RUC.bmp|EventTest1|EventTest0",130, 100, 15, 15,True)

GUISetState(@SW_SHOW)

While 1
    $msg = _GUISkinnedGetMsg($main_gui)
    consolewrite("$msg = " & $msg & @lf    )
    If $msg = $test0 Then
        _GUISkinned_Button_Event($test0)
    ElseIf $msg = $test1 Then
        _GUISkinned_Button_Event($test1)
    ElseIf $msg = $test2 Then
        _GUISkinned_Button_Event($test2)
    EndIf
    Sleep(50)
WEnd

Func EventTest0()
    msgbox(0,"test","arrow up click event")
EndFunc

Func EventTest1()
    msgbox(0,"test","arrow down click event")
EndFunc

Func EventTest2()
    msgbox(0,"test","Button click single event")
EndFunc

Func _GUISkinnedCtrlCreateButton($Skin,$x,$y,$h,$w,$twoState = False)
    Local $array,$ControlID
    $Skin = "0|0|" & $Skin 
    $array = StringSplit($Skin,"|")
    $array[0] = 0
    If Ubound($array) < 11 and $twoState then;not a Two state button
        SetError(1)
        Return -1
    ElseIf Ubound($array) < 7 and Not $twoState then
        SetError(1)
        Return -1
    ElseIf Ubound($array) = 7 and Not $twoState then
        Redim $array[11]
        Local $tempevent = $array[6]
        $array[6] = $array[3]
        $array[7] = $array[4]
        $array[8] = $array[5]
        $array[9] = $tempevent
        $array[10] = $tempevent
    EndIf
    $ControlID = GUICtrlCreatePic($array[3],$x,$y,$h,$w)
    Redim $GUISkinnnedSkinArray[$ControlID + 1]
    $GUISkinnnedSkinArray[$ControlID] = $array
    Return $ControlID
    
EndFunc
Func _GUISkinnedGetMsg($main_gui)
    Local $CursorInfo 
    $CursorInfo = GUIGetCursorInfo($main_gui)
    Return $CursorInfo[4]
EndFunc

Func _GUISkinned_Button_Event($ControlID)
    Local $CursorInf,$gui_msg,$array,$mousedown = 0
    $array = $GUISkinnnedSkinArray[$ControlID]
;loop until the controlID is diff (until mouse is out of focussed pic)
    Do
        $CursorInf = GUIGetCursorInfo()
        If Not $CursorInf[2] then;mouse not down
            if $array[0]=0 and $array[2] = 0 then
                GUICtrlSetImage($ControlID, $array[4])
                $array[2] = 1
                $array[1] = 0
            Elseif $array[0]=1 and $array[2] = 0 Then
                GUICtrlSetImage($ControlID, $array[7])
                $array[2] = 1
                $array[1] = 0
            EndIf
        ;this wil cause the mouse up event
        ;change the images first and launch the event function
            if $mousedown = 1 then
                $mousedown = 0
                if $array[0]=0 Then
                    GUICtrlSetImage($ControlID, $array[7])
                    $array[0] = 1
                    $GUISkinnnedSkinArray[$ControlID] = $array
                    Call($array[9])
                Else
                    GUICtrlSetImage($ControlID, $array[4])
                    $array[0]= 0
                    $GUISkinnnedSkinArray[$ControlID] = $array
                    Call($array[10])
                EndIf
            EndIf
        ElseIf $CursorInf[2] then;mouse down
            if $array[0]=0 and $array[1] = 0 then
                GUICtrlSetImage($ControlID, $array[5])
            ;$array[0] = 1
                $array[1] = 1
            Elseif $array[0]=1 and $array[1] = 0 Then
                GUICtrlSetImage($ControlID, $array[8])
            ;$array[0] = 0
                $array[1] = 1
            EndIf
            $array[2] = 0
            $mousedown = 1
        EndIf
    Until $CursorInf[4] <> $ControlID
;set the none mouseover pics
    if $array[0]=0 then
        GUICtrlSetImage($ControlID, $array[3])
    Else
        GUICtrlSetImage($ControlID, $array[6])
    EndIf
    $array[2] = 0
    $GUISkinnnedSkinArray[$ControlID] = $array
EndFunc

Doubble event specified by optional param

Not much errorhandling, but it's a start

EDIT:found a bug in it, try click hold down and move to other button and release (it should not do that)

Edited by TuMbLeWeEd
Link to comment
Share on other sites

Nice, but to me it seems like its just un-necessary coding where I can achieve the same effect using a much simpler and smaller function.

Do you having any disadvantages/advantages of using mine/your method?

qq

Link to comment
Share on other sites

Nice, but to me it seems like its just un-necessary coding where I can achieve the same effect using a much simpler and smaller function.

Do you having any disadvantages/advantages of using mine/your method?

<{POST_SNAPBACK}>

Your Disadvantages are things that i dont like for future maintenance;

-Defining arrays for all controls by hand=>mixing up array's with the wrong ControlID

-To much global params for the GUI wich are not ControlID's: like $U, $cursorinfo

-The same things are done at two different stages: in GUI loop and in Function (changing the images)

To hard to find the logic behind the code that way (have tons of code made that way that i dont now where the logic is=> i think it left me and took off to some country far away :"> )

You gonna have some troubble if you don't comment it a bit (try to see what it does in a coupple of months, again experiance :"> )

Note it runs on the beta, so they change somthing=>it's hard to keep track what is going wrong

Advantage: You made it, and it works (you know what to fix when it stops working)

Everyting has it's disadvantages, mine has to:

-I have to change the function strings in the skin string, they dont belong there

-More Funtions to handle the click-events (no extra praram's)

-The array in an array, if they stop supporting that=>Nothing is gonna work

Advantage: (for me)

-The array in an array is the only global var and it's made by the UDF, so the coder should not f*ck up the array

-I see a simpler setup with my code (the end result should not deffer to much from a normal gui in code, if i get there :( )

-I understand my own logic better :

-I only had to rearange your code :(

Link to comment
Share on other sites

Disadvantages I can see in yours.

- Once created you can't change the images. Unless you destroy the control and create a new one. Definatley not suited for me as the script I have provided this whole topic is purely an example and will be changed.

- I understand my own code/logic better :(.

Rest you said, comments >>>

-Defining arrays for all controls by hand=>mixing up array's with the wrong ControlID

<{POST_SNAPBACK}>

As said above, you can't change the images. Using my method (Image dir stored in array) all I need to do is simply change the array value to the new location. Simple. And I have carefully coded my script so that no variable names are used twice, unless they have a local scope inside a function.

-To much global params for the GUI wich are not ControlID's: like $U, $cursorinfo

<{POST_SNAPBACK}>

Can't do much about the $CursorInfo. I do not only use it for this but before even thinking about GUI skinning I used it, and still do in this script, for a function to move a window my clicking on a picture/label which requires GUIGetCursorInfo(). As for $U I could make a function has the parametre will be be filled by $U, that function the returns $U and continues to loop into another and the whole thing would never leave the local scope, thus never entering the global scope.

-The same things are done at two different stages: in GUI loop and in Function (changing the images)

<{POST_SNAPBACK}>

Continuing from above. Instead of having $U in global/local functions etc. I think I will add an extra element to the array, where $U will no longer be needed, and there will still be the same amount of variables/arrays (minus $U). The other reason I use $U is because I don't just change the image... obviously I don't make buttons that have no purpose except to change image. Depending on whether $U = 1 or whatever different functions are called.

You gonna have some troubble if you don't comment it a bit (try to see what it does in a coupple of months, again experiance  :"> )

Note it runs on the beta, so they change somthing=>it's hard to keep track what is going wrong.

<{POST_SNAPBACK}>

I understand all my code. If I made it, I understand it. If I didn't then I will learn it. As for the Beta comment. I am constantly updating my code to work with the latest Beta, not because it will cease to work but to add new features and shorten my already existing code.

----------------------

I think we both have valid points but its a personal opinion. I think I will stay with my method.

Thanks again.

qq

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...