PureBasic Forum
http://forums.purebasic.com/english/

Display an animation inside a system window
http://forums.purebasic.com/english/viewtopic.php?f=13&t=73107
Page 1 of 1

Author:  AlfaRomeo [ Sun Jun 30, 2019 10:45 am ]
Post subject:  Display an animation inside a system window

Hello,

It´s possible to display an animation inside a system window with system gadgets?

I tried to make it but when I click in the gadget to start the animation the program give me
the error: The specified #Sprite is not initialised in the code line
Code:
Select WaitWindowEvent()

even if I already have InitSprite() in the beginnig of the program :cry:

Author:  #NULL [ Sun Jun 30, 2019 10:52 am ]
Post subject:  Re: Display an animation inside a system window

Check if the actual creation of the spite is successful.
Are you using threads? Because that can cause your errors to be shown on a different seemingly unrelated line of code.

Author:  AlfaRomeo [ Sun Jun 30, 2019 11:07 am ]
Post subject:  Re: Display an animation inside a system window

#NULL wrote:
Are you using threads? Because that can cause your errors to be shown on a different seemingly unrelated line of code.


Yes, I use a thread

Code:
Procedure GetSprites(bat1,bat2,bat3,bat4)

  UsePNGImageDecoder()
  UseJPEGImageDecoder()
  battery=LoadSprite(#PB_Any,"D:\Store\New\Images\battery_strip.jpg",#PB_Sprite_AlphaBlending)
 
  bat1=CopySprite(battery,#PB_Any) : ClipSprite(bat1,0,0,86,34)
  bat2=CopySprite(battery,#PB_Any) : ClipSprite(bat2,86,0,86,34)
  bat3=CopySprite(battery,#PB_Any) : ClipSprite(bat3,172,0,86,34)
  bat4=CopySprite(battery,#PB_Any) : ClipSprite(bat4,258,0,86,34)
EndProcedure

Procedure GetBattery(period)    ;period will contain the value 30 passed by CreateThread()
ACtxt.s=""
batFlagTxt.s=""
lifeTimeTxt.s=""
 
Repeat
  GetSystemPowerStatus_(PowerStatus.SYSTEM_POWER_STATUS)    ;this must be inside main loop
   
  ac.d=PowerStatus\ACLineStatus              ; 0-Battery, 1-AC, 255 ou $ff-Desconhecido
  If ac=0
    ACtxt="Off"
  Else
    ACtxt="On"
  EndIf
 
  batFlag.d=PowerStatus\BatteryFlag
  ; BatteryFlag bits: 0- carga média, 1-Carga elevada, 2-Carga baixa, 4-Carga critica
                    ; 8-Em carga, 128-sem bateria, 255-Estado desconhecido
 
  If batFlag=0
    batFlagTxt="média" 
    DisplayTransparentSprite(bat3,0,0,255)
  ElseIf batFlag=1
    batFlagTxt="elevada"
    DisplayTransparentSprite(bat4,0,0,255)
  ElseIf batFlag=2
    batFlagTxt="baixa"
    DisplayTransparentSprite(bat2,0,0,255)
  ElseIf batFlag=4
    batFlagTxt="critico"
    DisplayTransparentSprite(bat1,0,0,255)
  ElseIf batFlag=8
    batFlagTxt="em carga"
  ElseIf batFlag=128
    batFlagTxt="sem bateria"
  ElseIf batFlag=255
    batFlagTxt="desconhecido"
  EndIf
     
  life100.d=PowerStatus\BatteryLifePercent        ; % de carga restante (255 ou $ff se desconhecida)
  lifeTime.l=PowerStatus\BatteryLifeTime          ; n. de segundos restantes (-1 ou $ffffffff se desconhecido)
  lifeTimeMin=lifeTime/60
  fullLife.l=PowerStatus\BatteryFullLifeTime       ; n. de segundos de autonomia (-1 ou $ffffffff se desconhecido)
   
    SetGadgetText(0,"Power "+ACtxt)
    SetGadgetText(1,"Carga da bateria: "+batFlagTxt)
    SetGadgetText(2,Str(life100)+" % de bateria restante")
    SetGadgetText(3,Str(lifeTimeMin)+" minutos de bateria restante")
    FlipBuffers()
    Delay(1000)
  ForEver
EndProcedure


InitSprite()
InitKeyboard()
OpenWindow(0,50,50,656,144,"Battery status",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0),300,0,356,144)

TextGadget(0,10,10,200,14,"")
TextGadget(1,10,30,200,14,"")
TextGadget(2,10,50,200,14,"")
TextGadget(3,10,70,200,14,"")

ButtonGadget(10,20,90,60,20,"Go")
ButtonGadget(11,100,90,60,20,"Stop")

Repeat
 
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      quit=1
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 10
          thread=CreateThread(@GetBattery(),30)
        Case 20
          If IsThread(thread)
            quitThread=1          ;need a global variable to safely exits the thread instead of using KillThread() directly
                                  ;which doesn't clean the stack correctly etc
            Delay(100)
            KillThread(thread)
          EndIf
      EndSelect
  EndSelect
Until quit=1

CloseWindow(0)

Author:  infratec [ Sun Jun 30, 2019 11:31 am ]
Post subject:  Re: Display an animation inside a system window

Your program will never do what you want :wink:

You never load the picture.

Attached a vie enhancements, but since I have no battery ...
Code:
Global.i bat1, bat2, bat3, bat4


Procedure.i GetSprites()
 
  battery=LoadSprite(#PB_Any,"D:\tmp\battery.jpg",#PB_Sprite_AlphaBlending)
  If battery
   
    bat1=CopySprite(battery,#PB_Any) : ClipSprite(bat1,0,0,86,34)
    bat2=CopySprite(battery,#PB_Any) : ClipSprite(bat2,86,0,86,34)
    bat3=CopySprite(battery,#PB_Any) : ClipSprite(bat3,172,0,86,34)
    bat4=CopySprite(battery,#PB_Any) : ClipSprite(bat4,258,0,86,34)
  EndIf
 
  ProcedureReturn battery
 
EndProcedure

Procedure GetBattery(period)    ;period will contain the value 30 passed by CreateThread()
 
  ACtxt.s=""
  batFlagTxt.s=""
  lifeTimeTxt.s=""
 
  GetSprites()
 
  Repeat
    GetSystemPowerStatus_(PowerStatus.SYSTEM_POWER_STATUS)    ;this must be inside main loop
   
    ac.d=PowerStatus\ACLineStatus              ; 0-Battery, 1-AC, 255 ou $ff-Desconhecido
    If ac=0
      ACtxt="Off"
    Else
      ACtxt="On"
    EndIf
   
    batFlag.d=PowerStatus\BatteryFlag
    ; BatteryFlag bits: 0- carga média, 1-Carga elevada, 2-Carga baixa, 4-Carga critica
    ; 8-Em carga, 128-sem bateria, 255-Estado desconhecido
   
    If batFlag=0
      batFlagTxt="média"
      DisplayTransparentSprite(bat3,0,0,255)
    ElseIf batFlag=1
      batFlagTxt="elevada"
      DisplayTransparentSprite(bat4,0,0,255)
    ElseIf batFlag=2
      batFlagTxt="baixa"
      DisplayTransparentSprite(bat2,0,0,255)
    ElseIf batFlag=4
      batFlagTxt="critico"
      DisplayTransparentSprite(bat1,0,0,255)
    ElseIf batFlag=8
      batFlagTxt="em carga"
    ElseIf batFlag=128
      batFlagTxt="sem bateria"
    ElseIf batFlag=255
      batFlagTxt="desconhecido"
    EndIf
   
    life100.d=PowerStatus\BatteryLifePercent        ; % de carga restante (255 ou $ff se desconhecida)
    lifeTime.l=PowerStatus\BatteryLifeTime          ; n. de segundos restantes (-1 ou $ffffffff se desconhecido)
    lifeTimeMin=lifeTime/60
    fullLife.l=PowerStatus\BatteryFullLifeTime       ; n. de segundos de autonomia (-1 ou $ffffffff se desconhecido)
   
    SetGadgetText(0,"Power "+ACtxt)
    SetGadgetText(1,"Carga da bateria: "+batFlagTxt)
    SetGadgetText(2,Str(life100)+" % de bateria restante")
    SetGadgetText(3,Str(lifeTimeMin)+" minutos de bateria restante")
    FlipBuffers()
    Delay(1000)
  ForEver
EndProcedure



UseJPEGImageDecoder()
InitSprite()
InitKeyboard()

OpenWindow(0,50,50,656,144,"Battery status",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
OpenWindowedScreen(WindowID(0),300,0,356,144)

TextGadget(0,10,10,200,14,"")
TextGadget(1,10,30,200,14,"")
TextGadget(2,10,50,200,14,"")
TextGadget(3,10,70,200,14,"")

ButtonGadget(10,20,90,60,20,"Go")
ButtonGadget(11,100,90,60,20,"Stop")

Repeat
 
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      quit=1
     
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 10
          thread=CreateThread(@GetBattery(),30)
        Case 20
          If IsThread(thread)
            quitThread=#True      ;need a global variable to safely exits the thread instead of using KillThread() directly
                                  ;which doesn't clean the stack correctly etc
            If WaitThread(thread, 500) = 0
              KillThread(thread)
            EndIf
          EndIf
      EndSelect
  EndSelect
Until quit=1

CloseWindow(0)

But it is far awy from the optimum and you have to enable thread safe in compiler options.

Author:  infratec [ Sun Jun 30, 2019 11:33 am ]
Post subject:  Re: Display an animation inside a system window

And why you want to use a sprite?

I think it would be easier with a CanvasGadget.

Author:  #NULL [ Sun Jun 30, 2019 11:33 am ]
Post subject:  Re: Display an animation inside a system window

- As I said, check the result of LoadSprite() and CopySprite()
- your GetSprites() is never called
- I don't know if you can call DisplaySprite() from a thread, especially without any thread management via mutexes/semaphores.
- Your sprite variables are local to GetSprites() and GetBattery() respectively, they can't see each other.

Author:  AlfaRomeo [ Sun Jun 30, 2019 12:19 pm ]
Post subject:  Re: Display an animation inside a system window

Thanks for the replies, I will try to implement your suggestions in my code and see if it will works.
I'm new in PureBasic and there is much I didn´t figured yet about how it works :?

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/