Display an animation inside a system window

Just starting out? Need help? Post your questions and find answers here.
AlfaRomeo
New User
New User
Posts: 7
Joined: Fri Jun 21, 2019 10:28 am

Display an animation inside a system window

Post by AlfaRomeo »

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 all

Select WaitWindowEvent()

even if I already have InitSprite() in the beginnig of the program :cry:
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Display an animation inside a system window

Post by #NULL »

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.
AlfaRomeo
New User
New User
Posts: 7
Joined: Fri Jun 21, 2019 10:28 am

Re: Display an animation inside a system window

Post by AlfaRomeo »

#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: Select all

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)
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Display an animation inside a system window

Post by infratec »

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: Select all

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.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Display an animation inside a system window

Post by infratec »

And why you want to use a sprite?

I think it would be easier with a CanvasGadget.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Display an animation inside a system window

Post by #NULL »

- 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.
AlfaRomeo
New User
New User
Posts: 7
Joined: Fri Jun 21, 2019 10:28 am

Re: Display an animation inside a system window

Post by AlfaRomeo »

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 :?
Post Reply