popovers
popovers
i'm new to PB on the mac. the examples in this forum are great. thank you for sharing the tips. does someone have suggestions for how to implement popover menus? for example, when clicking on a status item, showing a popover anchored to the status bar similar to programs like itsycal: https://www.mowglii.com/itsycal/
thank you in advance.
thank you in advance.
Re: popovers
In PureBasic, that's known as the system tray, and it's implemented as follows:mrbungle wrote:...how to implement popover menus? for example, when clicking on a status item, showing a popover anchored to the status bar...
Code: Select all
Enumeration
#mainWindow
#sysTrayIcon
#sysTrayMenu
EndEnumeration
LoadImage(#sysTrayIcon, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#mainWindow, 0, 0, 600, 400, "SysTray Example", wFlags)
AddSysTrayIcon(#sysTrayIcon, WindowID(#MainWindow), ImageID(#sysTrayIcon))
SysTrayIconToolTip(#sysTrayIcon, "My PureBasic Application") ;hover text
CreatePopupMenu(#sysTrayMenu)
MenuItem(0, "SysTray Menu 1")
MenuItem(1, "SysTray Menu 2")
MenuItem(2, "SysTray Menu 3")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_SysTray
If EventType() = #PB_EventType_LeftClick
DisplayPopupMenu(#sysTrayMenu, WindowID(#mainWindow))
EndIf
EndSelect
Until appQuit
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: popovers
thank you for your response! i'm familiar with the systray function but was thinking of the genuine function to flush windows against the menu bar and the status menu like with itsycal in my example. purebasic supports the menu capability but i assume it requires some direct cocoa interface?
Re: popovers
You can define the position of popup menu ...
Code: Select all
Enumeration
#mainWindow
#sysTrayIcon
#sysTrayMenu
EndEnumeration
LoadImage(#sysTrayIcon, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#mainWindow, 0, 0, 600, 400, "SysTray Example", wFlags)
AddSysTrayIcon(#sysTrayIcon, WindowID(#MainWindow), ImageID(#sysTrayIcon))
SysTrayIconToolTip(#sysTrayIcon, "My PureBasic Application") ;hover text
CreatePopupMenu(#sysTrayMenu)
MenuItem(0, "SysTray Menu 1")
MenuItem(1, "SysTray Menu 2")
MenuItem(2, "SysTray Menu 3")
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_SysTray
If EventType() = #PB_EventType_LeftClick
DisplayPopupMenu(#sysTrayMenu, WindowID(#mainWindow), DesktopMouseX() - 30, 30)
EndIf
EndSelect
Until appQuit
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: popovers
Thank you again! I hadn't released the desktopX and Y functions combined with a borderless window could simulate a popover.
is it safe to assume that with some cocoa wizardry using one of the examples posted in this forum i could intercept the menu bar click (status menu) and then display a popover window? i really want to draw the content for my app inside a window so i can rely on gadgets and images to display the information i need.
is it safe to assume that with some cocoa wizardry using one of the examples posted in this forum i could intercept the menu bar click (status menu) and then display a popover window? i really want to draw the content for my app inside a window so i can rely on gadgets and images to display the information i need.
Re: popovers
You don't need cocoa
Update
Update
Code: Select all
Enumeration Windows
#mainWindow
#popupWindow
EndEnumeration
Enumeration Gadgets
#popupContainer
#popupButtonExit
EndEnumeration
Enumeration MenuBars
;
EndEnumeration
Enumeration MenuItems
;
EndEnumeration
Enumeration SysTrays
#sysTrayIcon
EndEnumeration
Procedure PopOverWindow()
Protected mouse_x, x, y, dx, dy, cnt
dx = 200
dy = 400
cnt = ExamineDesktops()
mouse_x = DesktopMouseX()
x = mouse_x - dx / 2
y = 30
If (x + dx) >= DesktopWidth(0)
x = DesktopWidth(0) - dx - 10
EndIf
If OpenWindow(#popupWindow, x, y, dx, dy, "PopOver", #PB_Window_BorderLess)
StickyWindow(#popupWindow, #True)
ContainerGadget(#popupContainer, 0, 0, dx, dy, #PB_Container_Single)
;{
ButtonGadget(#popupButtonExit, dx / 2 - 40, dy - 40, 80, 30, "Close")
;}
CloseGadgetList()
EndIf
EndProcedure
LoadImage(#sysTrayIcon, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#mainWindow, 0, 0, 600, 400, "SysTray Example", wFlags)
AddSysTrayIcon(#sysTrayIcon, WindowID(#MainWindow), ImageID(#sysTrayIcon))
SysTrayIconToolTip(#sysTrayIcon, "My PureBasic Application") ;hover text
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_Gadget
Select EventGadget()
Case #popupButtonExit
;TODO
CloseWindow(#popupWindow)
EndSelect
Case #PB_Event_SysTray
If EventType() = #PB_EventType_LeftClick
If Not IsWindow(#popupWindow)
PopOverWindow()
EndIf
EndIf
EndSelect
Until appQuit
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Re: popovers
mrbungle wrote:...thinking of the genuine function to flush windows against the menu bar and the status menu like with itsycal in my example...
Instead of the NSPopover, this example utilises a transparent PNG to create a custom-shaped window which can be positioned as required and used as a dialog. Visually more interesting.
Code: Select all
; this example automatically downloads a PNG image from DropBox
InitNetwork()
UsePNGImageDecoder()
Enumeration
#mainWindow
#popupWindow
#sysTrayIcon
#sysTrayIconImage
#popupWindowShape
#popupWindowClose
#popupWindowCheck1
#popupWindowCheck2
EndEnumeration
;downloading popup window image from DropBox
If FileSize(GetTemporaryDirectory() + "customPop.png") < 1
ReceiveHTTPFile("https://www.dropbox.com/s/3im9yuvv0u932kn/customPop.png?dl=1",
GetTemporaryDirectory() + "customPop.png")
EndIf
LoadImage(#popupWindowShape, GetTemporaryDirectory() + "customPop.png")
LoadImage(#sysTrayIconImage, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
Procedure popupWindow()
ExamineDesktops()
popWidth = ImageWidth(#popupWindowShape)
popHeight = ImageHeight(#popupWindowShape)
popX = DesktopMouseX()- (popWidth / 2)
popY = 0
If (popX + popWidth) >= DesktopWidth(0) : popX = DesktopWidth(0) - popWidth - 10 : EndIf
OpenWindow(#popupWindow, popX, popY, popWidth, popHeight, "", #PB_Window_BorderLess)
StickyWindow(#popupWindow, #True)
popupWindowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(#popupWindowShape))
CocoaMessage(0, WindowID(#popupWindow), "setOpaque:", #NO)
CocoaMessage(0, WindowID(#popupWindow), "setHasShadow:", #YES)
CocoaMessage(0, WindowID(#popupWindow), "setBackgroundColor:", popupWindowShape)
CheckBoxGadget(#popupWindowCheck1, 60, 65, 80, 20, "Option 1")
CheckBoxGadget(#popupWindowCheck2, 60, 85, 80, 20, "Option 2")
ButtonGadget(#popupWindowClose, 60, 105, 80, 20, "DONE")
EndProcedure
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(#mainWindow, 0, 0, 400, 200, "Custom SysTray Example", wFlags)
AddSysTrayIcon(#sysTrayIcon, WindowID(#MainWindow), ImageID(#sysTrayIconImage))
SysTrayIconToolTip(#sysTrayIcon, "My PureBasic Application") ;hover text
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
appQuit = #True
Case #PB_Event_Gadget
Select EventGadget()
Case #popupWindowClose
CloseWindow(#popupWindow)
EndSelect
Case #PB_Event_SysTray
If EventType() = #PB_EventType_LeftClick
If Not IsWindow(#popupWindow)
popupWindow()
EndIf
EndIf
EndSelect
Until appQuit
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: popovers
this is great! thank you!
Re: popovers
Your examples were really helpful and have given me some ideas. I did notice that these custom popover windows don't seem to work on a second monitor. is there something special i need to do to force it to display on my other monitor?
Thank you for all of your help and generosity!
Thank you for all of your help and generosity!
Re: popovers
The examples didn't factor in multiple desktops. The calculation ensuring that the pop-up window does not exceed the desktop bounds utilises only the metrics of the primary desktop. Removing that condition solves the multiple-desktop issue. Just a two-line change to the popupWindow() procedure, like so:mrbungle wrote:...these custom popover windows don't seem to work on a second monitor...
Code: Select all
Procedure popupWindow()
ExamineDesktops()
popWidth = ImageWidth(#popupWindowShape)
popHeight = ImageHeight(#popupWindowShape)
popX = DesktopMouseX()- (popWidth / 2)
; [1] ###################
; change the popY value
popY = DesktopMouseY()
; #######################
; [2] #####################################################################################
; remove this line that validates the popX position against the primary desktop width
; If (popX + popWidth) >= DesktopWidth(0) : popX = DesktopWidth(0) - popWidth - 10 : EndIf
; #########################################################################################
OpenWindow(#popupWindow, popX, popY, popWidth, popHeight, "", #PB_Window_BorderLess)
StickyWindow(#popupWindow, #True)
popupWindowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(#popupWindowShape))
CocoaMessage(0, WindowID(#popupWindow), "setOpaque:", #NO)
CocoaMessage(0, WindowID(#popupWindow), "setHasShadow:", #YES)
CocoaMessage(0, WindowID(#popupWindow), "setBackgroundColor:", popupWindowShape)
CheckBoxGadget(#popupWindowCheck1, 60, 65, 80, 20, "Option 1")
CheckBoxGadget(#popupWindowCheck2, 60, 85, 80, 20, "Option 2")
ButtonGadget(#popupWindowClose, 60, 105, 80, 20, "DONE")
EndProcedure
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: popovers
Thank you again! This should be obvious to me but it wasn't. I had removed the Desktop(0) code before and it didn't work. I guess this is due to how coordinates are treated across multiple displays where the Y value assumes the primary display and the desktopY value is relative to the currently active display?
Re: popovers
Yes. A primary desktop with a 1920 x 1080 display begins at coordinate 0, 0, and ends at 1919, 1079.mrbungle wrote:...how coordinates are treated across multiple displays where the Y value assumes the primary display and the desktopY value is relative to the currently active display?
If there is a secondary desktop arranged to the right, it will have a starting X coordinate of 1920 (the width of the primary desktop), but not necessarily a Y coordinate of 0. This is because the secondary desktop can be aligned at different heights by the OS.
Similarly, if the second desktop with a 1280 x 1024 display is arranged to the left, it will have a starting X coordinate of -1280 (the width of the secondary desktop).
So, in left/right display arrangements, the X coordinates are relative to the primary desktop, but the Y coordinates are dependent on the arrangement of the desktops by the OS. But in top/bottom display arrangements, the coordinate rule is flipped.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel
Re: popovers
Ah. That makes sense. Appreciate the time and the explanation!