Page 1 of 2

Canvas-style gadget?

Posted: Tue Apr 27, 2004 9:56 pm
by syntax error
I'm considering re-writing a tool (Image Packer - See link in sig) written in BlitzPlus. In that language there is a CreateCanvas() function.

I'm giving PB Demo a test but struggling to find a suitable gadget ro display images and to be able to detect a Left/Right mouse click. Think MSPAINT.

Is there something similar in PB?
Frame3DGadget/ContainerGadget do not detect mouse clicks.

Posted: Tue Apr 27, 2004 10:10 pm
by BrendanE
It can be done - there is probably a better way - no doubt one of the forum guru's will enlighten me :) - but I got around it anyway by processing the WM_LBUTTONDOWN WM_RBUTTONDOWN messages and checking that the mouse was within my 'canvas' area (which was in my case an ImageGadget).

Posted: Tue Apr 27, 2004 10:19 pm
by USCode
Not sure if it's totally what you are looking for but check out the code provided here by einander:

viewtopic.php?t=8860&highlight=grid

Posted: Tue Apr 27, 2004 11:53 pm
by MadMax
I'm considering re-writing a tool (Image Packer - See link in sig) written in BlitzPlus. In that language there is a CreateCanvas() function.
I think this is what you want OpenWindowedScreen()

Posted: Wed Apr 28, 2004 6:19 am
by carolight
This is how I did the left click in an imagegadget (I've probably lifted this, so credit goes to whoever!)

Code: Select all

OpenWindow(0, 0,0, 640,480, #PB_Window_SystemMenu | #PB_Window_WindowCentered | #PB_Window_MaximizeGadget |#PB_Window_MinimizeGadget, " ")
  
CreateGadgetList(WindowID(0))
CreateImage(0, 100,100) ; this is the main image gadget
UseImage(0)
StartDrawing(ImageOutput())
FillArea(0,0, RGB(255,0,0), RGB(255,0,0))
StopDrawing()
ImageGadget(1, 200,200,100,100, UseImage(0))

Procedure.l CheckPos(GadgetImageNo.l)
  blInScroll.l = #False
  ;The following API commands are not available in Demo
  GetCursorPos_(mouse.POINT)   
  ScreenToClient_(GadgetID(GadgetImageNo), mouse) 
  If mouse\x >= 0 And mouse\y >=0
    If mouse\x < GadgetWidth(GadgetImageNo) And mouse\y < GadgetHeight(GadgetImageNo)
      blInScroll = #True
    EndIf
  EndIf
  ProcedureReturn blInScroll
EndProcedure

Repeat
  event = WaitWindowEvent()
  Select event
    Case #WM_LBUTTONDOWN
      If CheckPos(1)  ; Check if click is in image 1
        MessageRequester("", "Left Click in Image")
      Else
        MessageRequester("","Left Click NOT in Image")
      EndIf
      
  EndSelect
Until event = #PB_Event_CloseWindow
End
Unfortunately this code can't be run in the demo, due to the 2 API commands.

I have recreated a image list box like this, within a scroll area. First I check that the co-ords are in the scrollgadget, then which image they're in.

Posted: Wed Apr 28, 2004 10:26 am
by Fred
here a little sample of paint like program (with a brush) using the OwnGadget() user library (which can be found here: viewtopic.php?t=10477). Once the drawing is done, don't forget to save your wonderful painting :wink:

BTW: I will probably add a native CanvasGadget() as it seems a bit difficult to do it else.

Code: Select all

; 
; Little 'paint' like program, based on the OwnGadget() library.
;
; By AlphaSND - 2004
;

#ImageWidth  = 320
#ImageHeight = 200

#GadgetX = 10
#GadgetY = 40

Global EraseMode

Procedure paint(gadget)
  ;notice that startdrawing()/stopdrawing() is not requied....
  DrawImage(UseImage(0), 0, 0)
EndProcedure


Procedure mouse(gadget,button,x,y)
  Static ButtonPushed
 
  UseImage(1)
      
  HalfImageWidth  = ImageWidth()/2
  HalfImageHeight = ImageHeight()/2      
 
  If x < HalfImageWidth  : x = HalfImageWidth  : EndIf
  If y < HalfImageHeight : y = HalfImageHeight : EndIf
  If x > #ImageWidth-HalfImageWidth   : x = #ImageWidth-HalfImageWidth   : EndIf
  If y > #ImageHeight-HalfImageHeight : y = #ImageHeight-HalfImageHeight : EndIf
 
  UseImage(0)
 
  If button = 1 And (ButtonPushed = #False Or EraseMode = #True) And StartDrawing(ImageOutput())
    UseImage(1)
    DrawImage(ImageID(), x-ImageWidth()/2, y-ImageHeight()/2)
    
    StopDrawing()
    
    InvalidateRect_(gadget, 0, 0)
    
    ButtonPushed = #True
  Else
        
    If StartDrawing(WindowOutput())
           
      DrawImage(UseImage(0), #GadgetX, #GadgetY) ; just redraw the background before displaying our 'overlay' picture
          
      BrushX = x+#GadgetX-HalfImageWidth
      BrushY = y+#GadgetY-HalfImageHeight
      
      DrawImage(UseImage(1), BrushX, BrushY)
      StopDrawing()
    EndIf
  EndIf
  
  If button = 0
    ButtonPushed = #False
  EndIf
  
EndProcedure

CreateImage(0, #ImageWidth, #ImageHeight)

CreateImage(1, 1, 1)
StartDrawing(ImageOutput())
  Plot(0, 0, RGB(255, 0, 0))
StopDrawing()

CreateOwnGadgetType("MyOwnCanvas", -1, "")

OpenWindow(0,0,0,340,270,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered,"")

CreateGadgetList(WindowID())
  
  ;Create a gadget of the previous created type...
  ;
  Canvas = OwnGadget("MyOwnCanvas", #GadgetX, #GadgetY, #ImageWidth, #ImageHeight)
  PaintCallback(Canvas, @paint())
  MouseCallback(Canvas, @mouse())
  
  ButtonGadget( 0, 10, 10, 60, 25, "Red Plot")
  ButtonGadget( 1, 80, 10, 60, 25, "Green Box")  
  ButtonGadget( 2, 150, 10, 60, 25, "Eraser")    


CreateMenu(0, WindowID())
  MenuTitle("File")
  MenuItem(0, "Save As..."+#Tab$+"Ctrl+S")
  MenuBar()
  MenuItem(1, "Quit")

UsePNGImageEncoder()

Repeat
  event=WaitWindowEvent()
  
  If Event = #PB_Event_Menu
  
    Select EventMenuID()
    
      Case 0
        File$ = SaveFileRequester("","","PNG Files|*.png", 0)
        
        If File$
          If LCase(GetExtensionPart(File$)) <> "png"
            File$+".png"
          EndIf
          
          SaveImage(0, File$, #PB_ImagePlugin_PNG)
        EndIf
      
      Case 1
        Event = #PB_Event_CloseWindow  ; Quit 
        
    EndSelect
  
  ElseIf Event = #PB_Event_Gadget
  
    Select EventGadgetID()
    
      Case 0
        CreateImage(1, 1, 1)
        StartDrawing(ImageOutput())
          Plot(0, 0, RGB(255, 0, 0))
        StopDrawing()

        EraseMode = #False
        
      Case 1
        CreateImage(1, 6, 6)
        StartDrawing(ImageOutput())
          Box(0, 0, 6, 6, RGB(0, 255, 0))
        StopDrawing()
        
        EraseMode = #False

      Case 2
        CreateImage(1, 50, 50)
        EraseMode = #True
        
    EndSelect
  EndIf
  
Until Event = #PB_Event_CloseWindow

Posted: Wed Apr 28, 2004 6:36 pm
by syntax error
Thanks for the help guys. Unfortunately, very little works in the demo due to no WinAPI support.

OpenWindowedScreen() asked me to InitSprite first.
ImageGadget() is as near as I can get. Although this means I have ensure a 'left/right mousedown' is within the gadget region first.
I will probably add a native CanvasGadget() as it seems a bit difficult to do it else.
Yes please Fred. In particular it needs to detect the mouse clicks/mouse down and be able to display a large image which is automatically cropped.

EDIT
After some playing around I have this example.
For some reason I can't get the brush image (a green circle) to show up in the canvas image.

Any ideas??

Code: Select all

; canvas test

#canW=244
#canH=212

canvas=CreateImage(#pb_any,#canW,#canH)
brush=CreateImage(#pb_any,64,64)
UseImage(brush)
StartDrawing(ImageOutput())
Circle(32,32,30,RGB(100,255,80))
StopDrawing()

; gui
win=OpenWindow(#pb_any, 200,200,#canW+46, #canH+66, #PB_Window_SystemMenu | #PB_Window_TitleBar , "Test window")
If CreateGadgetList(WindowID(win))
  igad=ImageGadget(#pb_any, 20, 20, 190, 150, UseImage(canvas),#PB_Image_Border)
EndIf
sb=CreateStatusBar(#pb_any,WindowID(win))
StatusBarText(sb, 0, "left-click in canvas ...")

quit=0

Repeat
  ev=WaitWindowEvent()
  Select ev
    Case 513 ; mousedown
    x=WindowMouseX()-20-6 : y=WindowMouseY()-20-24
    StatusBarText(sb, 0, "Coords: "+Str(x)+","+Str(y))
    UseImage(canvas)
    StartDrawing(ImageOutput())
    ; Box(0,0,#canW,#canH,0) ; CLS
    DrawImage(brush,x-32,y-32)
    StopDrawing()
    SetGadgetState(igad,UseImage(canvas))
    Case #PB_EventCloseWindow : quit=1
  EndSelect
Until quit=1

End

Posted: Thu Apr 29, 2004 8:20 pm
by MadMax
maybe this will help.

Code: Select all

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf

InitSound()

fps.f=85
gfps.f=85
rfps.f=1
rfpss.f=85

infoon=0

mousplace=0



   hWnd=OpenWindow(0,0,0,800,600,#PB_Window_SystemMenu|#PB_Window_WindowCentered|#PB_Window_MinimizeGadget,"Dabidu")

If hWnd=0
MessageRequester("Error","Can't open window.",0)
EndIf
 
   X=OpenWindowedScreen(hWnd,0,0,640,480,0,0,0)
   SetFrameRate(60)
  
If X=0
MessageRequester("Error","Can't open screen.",0)
EndIf

CreateSprite(0,16,16)

StartDrawing(SpriteOutput(0))
DrawingMode(4)
FrontColor(0,255,0)
Box(0,0,16,16)
DrawingMode(0)
FrontColor(0,0,0)
Box(0,5,16,6)
Box(5,0,6,16)
DrawingMode(4)
FrontColor(0,255,0)
Box(7,7,2,2)
StopDrawing()

    fpss=ElapsedMilliseconds()

 

 Repeat
    
    FlipBuffers()
    
    ClearScreen(0,0,0)
    
;========================================================================================
;                 FPS
;======================================================================================== 
    conta=conta+1

  If ElapsedMilliseconds()=>fpss+1000
   fpss=ElapsedMilliseconds()
   fps=conta
   rfps=gfps/fps
   rfpss=fps*rfps
   conta=0
  EndIf
;=========================================================================================
If WindowMouseX()<4 Or WindowMouseX()>641 Or WindowMouseY()<23 Or WindowMouseY()>500
ReleaseMouse(1)
mousplace=0
Else
ReleaseMouse(0)
If mousplace=0
mousplace=1
MouseLocate(WindowMouseX(),WindowMouseY())
EndIf 
EndIf

ExamineMouse()

mx=MouseX()-8
my=MouseY()-8


If mousplace
DisplayTransparentSprite(0,mx,my)
EndIf 

If MouseButton(1)

lmbtim=ElapsedMilliseconds()

EndIf 

If MouseButton(2)

rmbtim=ElapsedMilliseconds()

EndIf 

;=========================================================================================

;=========================================================================================
;                 PRINT TEXT
;========================================================================================= 

pepeID=ScreenOutput()
  
 StartDrawing(pepeID)
 
If infoon=1
 
   FrontColor(255,255,255)
   DrawingMode(1)
   Locate(20,20)
   DrawText("FPS: "+StrF(fps))
   FrontColor(255,0,0)
   Locate(20,40)
   DrawText("Correction: "+StrF(rfps))
   Locate(20,60)
   DrawText("Simulated FPS: "+StrF(rfpss))
   
EndIf

FrontColor(255,255,0)
DrawingMode(1)

If ElapsedMilliseconds()<lmbtim+1000
Locate(mx-25,my-15)
DrawText("LMB")
EndIf

If ElapsedMilliseconds()<rmbtim+1000
Locate(mx+15,my-15)
DrawText("RMB")
EndIf

   
 StopDrawing()

;=========================================================================================
;=========================================================================================   
;### Check for windows events   
      Eve= WindowEvent()  
      Select Eve
        Case #PB_Event_CloseWindow              
        End                                      
      EndSelect
     

;=========================================================================================
;               KEYBOARD INPUT
;=========================================================================================     
    ExamineKeyboard()
      
    
If KeyboardReleased(#PB_Key_F1)

  Select infoon
  
    Case 0
    
    infoon=1
    
    Case 1
    
    infoon=0
    
  EndSelect
  
EndIf


;=========================================================================================
;=========================================================================================    
 Until KeyboardPushed(#PB_Key_Escape)
 

End   

Posted: Thu Apr 29, 2004 9:00 pm
by Edwin Knoppert
How brilliant is this createcanvas() ??

Most DC's are driver based, like screen or printer.
I wonder if this call can set custom DPI stuff.
That would make my day..

Posted: Thu Apr 29, 2004 9:32 pm
by syntax error
@MadMax,
How system-friendly is that code example?
I see InitSprite()

Whats the difference between sprites/images?
I need masking support for sure.

My current method is this example ...

Code: Select all

; canvas test

#canW=420
#canH=380

Global canvas,mouseincanvas,x,y,igad,clscolor
Declare DrawBrush(can,xpos,ypos)
Declare ClsCanvas(can,r,g,b)

canvas=CreateImage(#pb_any,#canW,#canH)
brush=CreateImage(#pb_any,32,32)
UseImage(brush)
StartDrawing(ImageOutput())
Circle(16,16,14,RGB(100,255,80))
StopDrawing()

; gui
win=OpenWindow(#pb_any, 200,200,#canW+46, #canH+66, #PB_Window_SystemMenu | #PB_Window_TitleBar , "Canvas")
If CreateGadgetList(WindowID(win))
  igad=ImageGadget(#pb_any, 20, 20, 190, 150, UseImage(canvas),#PB_Image_Border)
EndIf
sb=CreateStatusBar(#pb_any,WindowID(win))
StatusBarText(sb, 0, "left-click in canvas ...")

quit=0
clscolor=0

Repeat
  ev=WaitWindowEvent()
;;;  Debug ev
  ; update stausbar with mouse coords
  x=WindowMouseX()-20-5 : y=WindowMouseY()-20-24
  If (x>=0 And x<#canW) And (y>=0 And y<#canH)
    mouseincanvas=1
    StatusBarText(sb, 0, "Coords: "+Str(x)+","+Str(y))
  Else
    mouseincanvas=0
    StatusBarText(sb, 0, "Coords: xxx,xxx")
  EndIf

  Select ev
    Case 513 ; LMB pressed
      If mouseincanvas
        drawmode=1 : DrawBrush(canvas,x,y)
      EndIf
    Case 514 
      drawmode=0 ; LMB released
    Case 512 ; mouse moving
      If drawmode=1
        DrawBrush(canvas,x,y)
      EndIf
    Case 516 ; RMB
      ClsCanvas(canvas,Random(255),Random(255),Random(255))
    Case #PB_EventCloseWindow : quit=1
  EndSelect
Until quit=1

End

Procedure DrawBrush(can,xpos,ypos)
    If mouseincanvas=1
      UseImage(can)
      StartDrawing(ImageOutput())
      Circle(xpos,ypos,12,RGB(100,255,80))
      StopDrawing()
      SetGadgetState(igad,UseImage(can))
     EndIf
EndProcedure

Procedure ClsCanvas(can,r,g,b)
  Static bkgcolor
  bkgcolor=RGB(r,g,b)
  UseImage(can)
  StartDrawing(ImageOutput())
  Box(0,0,#canW,#canH,bkgcolor) ; CLS
  StopDrawing()
  SetGadgetState(igad,UseImage(can))
EndProcedure
Anyone know the #CONST for 'window lost/gained focus'?
Is there an AutoSuspend call to put a PB app to sleep?

Posted: Thu Apr 29, 2004 11:20 pm
by MadMax
How system-friendly is that code example?
Very friendly, I'd say. Well as long as the PC has DirectX 7.

Not 100% sure, but maybe image doesn't need DirectX.

One of the nice features of PB is thatyou can combine 2D drawing, sprite, sprite3D and 3D with no or little hassle.

:D

Posted: Thu Dec 14, 2006 7:35 pm
by Guimauve
Fred wrote:BTW: I will probably add a native CanvasGadget() as it seems a bit difficult to do it else.
Sorry to bump an old topic but ...

The question is : CanvasGadget() devellopement is dead or is still on the todo list ?

Regards
Guimauve

Posted: Thu Dec 14, 2006 8:02 pm
by Fred
It's still on the big TODO list..

Posted: Thu Dec 14, 2006 9:00 pm
by Guimauve
Ok good !!

Regards

Posted: Wed Jun 27, 2007 1:38 pm
by real
The link to the OwnGadget user lib is dead, could anybody link to a downloadable one?