Hi All,
A little excercise for anyone interested. I’ve asked a few questions in the past, so some might recognise, for those who don’t I’m just a hobbiest making apps for my own interest.
Anyway, I have a project here I use that has a list box on the screen populated with records from a DB. There are about 8 columns of fields and I would like to be able to click on a row and using the ShowPopover command present a summary of the info for that record on either a small window or container. The problem is tho, that I want it to be aligned with and point at the row.
I can use the Listbox as the parentControl but it only points at the border/s of the ListBox. I can’t specify the actual row/column etc.
I then had the idea of adding a Label to the main screen with either no text or visibility off and then, after clicking the Listbox, set it’s Top and Left properties to a calculation based on the row & column properties. I could then point the info box at that.
Now, in principle this works but, nothing appears. I’m certain that the problem is that when I set the Label’s Top & Left it then positions itself under the ListBox and so is hidden.
Does anybody know if I’m correct there and, if so, can I tell it to be on top? I can’t find any reference to a “stack” type order.
Is there another way to achieve what I want that anyone can think of?
Hi Beatrix,
Yes, I thought that I needed to do some “trickery”, that’s what I was using the Label for. Prob is, it drops under the Listbox. Would a canvas not do that?
dim theRow as AppleListboxRow = LBMailboxes.GetSelectedRow
if theRow = Nil then Return
dim row as Integer = LBMailboxes.GetChildRowNumber(theRow)
dim yCoordinate as Integer = ((row - LBMailboxes.scrollPosition) * LBMailboxes.RowHeight) + LBMailboxes.RowHeight/2
dim xCoordinate as Integer = LBMailboxes.Width/2
Ok. I was having a play with the MouseUp & MouseDown events for the List box, but, whilst basically working, I think there are some other issues.
Thanks for your code, I don’t really understand a lot of it on face value. Where am I placing it - which event?
I’ve entered that into an event just to see what comes up. I don’t know where you got AppleListboxRow or LBMailboxes from. Are they built in or have you defined them as properties and, if so, what are they/
Sorry to seem so unknowledgeable but, as I’ve often stated, I’m a self-taught hobbiest.
I have a listbox subclass which is using a function getSelectedRow. Instead you need getSelectedRowIndex.
I show the popover after a context menu. The context menu of the listbox row already has x and y coordinates. But when called from the context menu of the bottom bar then I need the calculation.
Hi,
Again, thanks for the reply. I understand creating your own class etc as part of OO programming but I don’t know how to do it etc., so I don’t understand a lot of your code. I am having success now with having a “dummy” canvas and moving that around the screen as a target for the popup window/container tho so you’ve still helped heaps
The item that is circled - drag it to the navigation area at the left of the IDE window. You’ll see it probably named Class1 over there. In the Inspector you see this:
As you see in the Inspector you can now rename it. Now you’ve created your own class. If you also put something in the box labelled Super, (such as DesktopCanvas, DesktopTextaArea, etc) you thus create a subclass of that item.
Now you can add properties and methods to your class or subclass, as you require. And if it’s a subclass it will have events you can add.
If you now drag the subclass from the Navigator area into your layout, you create an instance of the subclass in the layout. Or you can create one in code this way:
[RN] The DesktopWindow.ShowPopover / DesktopContainer.ShowPopover / WebContainer.ShowPopover signature now takes two new optional arguments to provide the x and y coordinates where the popover is meant to be shown relative to the ParentControl bounds. The new signature on DesktopWindow, for example, is:
DesktopWindow.ShowPopover(parentControl As DesktopUIControl, displaySide As DesktopWindow.DisplaySides = DesktopWindow.DisplaySides.Bottom, detachable As Boolean = True, animated As Boolean = True, x As Integer = -1, y As Integer = -1)
Hi Tim,
As usual, thanks for your reply. I’ve tried in the past to come to grips with Object Oriented Programming and, if I’m right, this is what we are talking about, yes? Creating a subclass of an already existing control is how one can take the basics and make their own changes. Eg add in an Event, Method or Property that doesn’t currently exist but that they want. Am I right here?
If so, your example was good up to how to create the actual class/subclass and I created a small “test” app with a window and I added a Class control. I called it “testClass” and I set the Super via a couple of drill downs to a Label (something simple). All good, it inherited all of the functions etc of the Label control. How, though do I then add in my own functions to this control? Of course, I could be totally on the wrong track.
Yes, you are in the right direction, however, you don’t have to invent any extra functionality for a subclass to be of use. For example someone asked how to have a Label control that used a different font. This could be achieved using a Subclass of the standard label control.
Class MyLabel Super Label
Event Opening class MyLabel
Super.Opening
Self.FontName = "The Font I want"
Self.FontSize = 20
End Event
The MyLabel control will now appear in the Library and can be dragged into a window. When used it shows with the font name and size required. This is an example of a Subclass that doesn’t add any extra properties or events, it just overrides stock behaviour.
Hi Ian, thanks. I can see where this would be useful. For example, I like to use Helvetica Neue as my default font so if I redid any controls that use a font with HN as subclasses then I could use them on my apps from the start and so wouldn’t have to change them (?)
But, I was always of the impression that creating these “subclasses” were also a way to modify the original so as to add a function or property that didn’t already exist.
Anyway, quick question for anyone reading this and, back to my original topic (in a way), I’ve now got functional versions of the ShowPopover method working but is there a way to make the window close without clicking outside it’s boundaries or dragging it around and exposing the close control in the top left corner.
I am using one to add a record and after I’ve clicked a “save” button on that window, I would want it to close.
Assuming its name is “window” I’ve tried the obvious - window.Close. That doesn’t work and so I thought that would be because it doesn’t actually exist as “window” so I was looking at the idea of closing the instance I created originally.
var c As New window
c.ShowPopover( …etc
(note, this is called in a routine on a window called MainWindow)
So I was intending to use c.close or even MainWindow.c.close but, c does not have a close event. In fact it doesn’t have any events! How/where does this window exist and how do I access it?
When you click anywhere else the window should close on its own.
Classes are for managing complexity. If your window has too many methods and you constantly wonder which method is calling which then it’s time to invest in learning about classes.
You could use the observer pattern to have your window react to the popover. I think the Xojo examples have something on this pattern.
Window is an example of a SuperClass. In other words it is the class from which all of your Windows are SubClassed from. (at least most of the time). As such it is perfectly valid to say:
Method DisableAllControls( AnyWindow as Window )
// loop over controls in the window
// and disable them
End Method
This method could them be passed Any type of Window that had been SubClassed from Window. Don’t try and use the code it doesn’t actually run. It’s only a concept to explain something.
There is something special, however, about the Window class. It has no appearance. Only one appearance can exist for any given window class. You can’t say:
Var oWindow as New Window
oWindow.Show() // what would it look like?
You can make your own Abstract window classes your self. For example you could have a window class that represented a Bird and another for a Frog. Let’s assume you want to be able to pass either if there to a method, but not other classes of Window.
You can do this by having a class called Animal, which has a Super of Window. Then Bird and Frog can have a Super of Animal.
What you can’t do is insert a Window to your application and call it Animal. Then insert Frog as set it’s Super to Animal. This would mean that there are two layouts for Frog (one that is visible when you click on Animal and another when you click on Frog).
What you must do is insert a Class, set its name to Animal and its super to Window. Then it has no appearance. You can then add your Frog and set its super to Animal.