INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Building Ribbon Functionality in Application

Building Ribbon Functionality in Application

(OP)
Hi All (And Mike),
I decided to start a new thread since the other was about a pageframe property, this is gone down the path of really creating based on a different idea, which splintered from that discussion.

So I have encountered one weird issue. Originally I put a container with just a label in it, but I want to "mimic" the current Office style ribbon bar. (I find it does look quite good). And the way they "highlight" the active tab is by drawing a sort of 3 line frame around it (left, top, right). I initially thought I would just turn the border property on the container to width = 1, and when I lost focus to width = 0, but when I leave the object, (even when lost focus calls for a refresh) the container keeps it's boarder. Am I doing this the wrong way?

I tried a second method, putting an actual box in the container, and a "line" at the bottom to mimic the state of the bottom of the tab, where I set the color property either equal to the form background property (when the container/tab is selected), and to the border color of the pageframe when it's not selected. Then set the visible property of the box to either .T. or .F. depending on got or lost focus, but the box persists once the container has been clicked on.

It seems the refresh clause shouldn't need to be called when the lostfocus has the visibility property changing from True to False...

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

(OP)
Ok, so strangely my "lostfocus" event is never firing. Is there something "magic" about container's I'm not aware of?
I click on the object, even set a "gotfocus()" call from the click event. When I click on another button, it just goes to that button, and the code in the lost focus of the container never fires...

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

The LostFocus event for a container has the same nature as for the form:

Quote (help)

A form loses the focus when the form has no controls, all its controls have their Enabled and Visible properties set to false (.F.), or another form gets the focus.
Just put in container instead of form.

You will not want to control this with focus, even when the tab you emulate has focus for the moment the user activates the page, the next step will put the focus on some control within the page. So you want something that is not at all controlled by the focus. You want something that changes the active tab look as long as another tab becomes active. Focus is the totally wrong concept in this context, as the focus is always just on one single control, it is not at the same time on parents, they only are active, but focus is really only a very atomic thing.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

This is a classical issue of first setting all instances to some defaults and then only set the one currently activated instance different.

Here's how I would go about this: When you have a series of self-made tabs on your form, then let's assume they all are based on a class tabcontainer. You design it with the look for an inactive tab, on click you change its look to activated by setting some parts visible or invisible or change color or width. You do that after you reset all such tabs to their default look using SetAll("prpoerty",value,"tabcontainer") so theis SetAll influces all tabcontainers. Or use the objects ResetToDefault(). You can combine this by using one triggering property and define a property_assign method, which does This.ResetToDefault(...) on some if its properties.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

I was about to say that getting or losing focus is not relevant here; you need to be concerned with focusing of the controls on the page, not of the device that selects the page. But I see that Olaf has already made that point.

You mentioned the "refresh clause". If you mean the Refresh method, that is not relevant either. Refreshing a control serves no purpose unles the control is bound to data, which is not the case here. (Or did you mean something else by "refresh clause"?)

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Building Ribbon Functionality in Application

(OP)
Wow, feeling particularly stupid at the moment. I had always thought the Refresh() clause was related to all elements of the object, so if a color change, you needed to do a refresh of that object for it to be reflected on the form. Didn't realize until now it's only related to data... There are a bunch of refresh calls I can get rid of... (And I'm going to go do a global search for it across my forms...)

That said, I'm more confused now. It must mean that calls to things like This.BoarderWidth = 0 are not getting executed. That could be because I have them in the LostFocus method. (Sorry Mike I said "Refresh clause" earlier, and I did mean the Refresh method, but bu "claus" I mean the actual snippet in the method. "Clause" is a carry over from other programming language days).

I also thought by calling the refresh() method, any other changes I had would be affected there, so by calling the refresh method directly with a This.BoarderWidth = 0 would also be executed. But the "Lost Focus" event isn't happening when the container loses the focus... for reasons Olaf described (which I find a weird way to describe "lost focus", compared to all other objects, except forms, as he's also pointed out.

Let me tinker with this newfound understanding, and see if I can make it work. I also didn't realize there was a pagetab object. Another "Mr. Obvious", as Olaf mentioned it, a little bell went off in my head, so I may instead, tinker with that object too.

Thanks for all the good insights lads.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Scott, your new understanding is correct. As you have now realised, you do not need to call the Refresh method to give effect to things like colours and borders. In fact, there is a penalty in doing so, in that if the control happens to be bound to data, then it takes time for VFP to get that data in order to refresh the control.

Regarding the "pagetab" object - actually, there is no such thing. There is a page object, which displays many of the characterstics of of the actual tab. For example, if you set the page's BackColor to red, then the tab will appear red (sorry if I'm stating the obvious). But the tab doesn't exist as a separate object.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads

RE: Building Ribbon Functionality in Application

(OP)
Tom,
I've decided to do it from scratch. I looked at Emerson's Themed Controls, but that one has two problems: 1) He's not finished the ribbon, and more importantly 2) it's really based on the look and feel of the Office 2007/WinXP style ribbon which is a bit garish in my view. I tried to get it to run, and it had all kinds of control issues as well, so with the level of complexity of the incomplete item, I decided to pass.

Guillermo's FoxRibbon appearance is also based on the 2007/WinXP look and feel. Maybe that can be tailored/toned down, but I also like the notion of my approach being much simpler, and some things I like to *know* the functionality of it, rather than accepting a black box.

The funny little stumble I had above with the controls is now solved with the simple understanding of how container applies Got/Lost focus. That's now completely resolved, and the feel of the bar is just like that of current Office versions. I've embedded a screen shot of the bar here:



As you can see, the outline of the tab selected is just like what it looks like in modern office. You can see also, the "Configuration" menu is selected, and the corresponding tab is showing "Configuration". So with all this behaviour now working, I can start to populate the individual pages in the frame (which is set to width of screen at start, and resized if the size changes), with controls to do what I wish. I also will add a "Expand/Contract" button at the end of the page so the ribbon can be opened/closed, which I plan to do by simply setting the size of the height to 0 and move open windows relative to their position in the screen when it expands or contracts.

I think I'm 75% of the way done now, and that seems to have been the hardest part. The rest now is just like manipulating a pageframe and use it's objects to control everything else.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

(OP)
Hi Mike,
Thanks, I was aware of the page properties, and I have since found I misunderstood Olaf's comment on that, as I couldn't find a tab class when I went to make one.
BUT, funny enough, I realized that my "usage" of "Refresh" wasn't entirely wrong either... and if I make a call to it, it does what I tell it to do. The problem I had was calling it from the lostfocus method which was never actually getting fired, for reasons I now understand. What I did find is that "CLICK" event is your friend. So what I do on each of the buttons now, is call all their Refresh() methods, where I put the code to get the behavior I want. I supposed I could move all that to every button's click event, and then call all the buttons click events when one is clicked, but I "LOVE" the obvious meaning of "Refresh". Your point about data being bound is an interesting one, but does it really slow it down if there isn't anything to call? If that's the case, what I may do instead is create a custom method called "FakeTabRefresh" or something like that that I call instead of the native Refresh, and then I still get the benefit of having some reminder in the method of what is going on. That's why I didn't want to use "click" because it feels obscure, and not very informative of what is actually going on when you're hopping across programmatically "clicking" everything.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

I was referring to your pagetab class, as you said you made your own tabs on a pageframe with tabs=.f.
I assumed you defined a class for that. Are you really putting containers with labels on the form and program in them on the form itself? Make use of OOP.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Hi Olaf,
I have a set of buttons what are a sub-class, and all of which use OOP and inheritance to function. Since the Pageframe without tabs exists then you just need some way to tell the button (which is no unique to the ribbon, but I use in many other places), one with text one with image, but they are both based on the same sub-class "Modern Button" which is a container with 1 object in it. In the case of the tabs, I added one object to the container, a "line" so that when the button is selected, it's bottom border can be over-ridden with the line, and set color properties to what you wish. It's elegant, simple and I just had to work out the "refresh" behaviors, now it all works like a charm. All the buttons really do is create an appearance (behavior as seen in the image above), and then setting the page that they are related to. Adding more is easy now, I can even subclass these as "TabButton" so they are easy to apply. The leading button is a little bit different, but it essentially will call an overlaying modal form when it's selected, which is same behavior as Office.
This approach is much simpler than all the others I've seen, and I don't see the point of making them overly complex to the extent that they don't work in other settings. What I'm planning to do now is actually subclass the "Main" form so any new application can use this, and you just have to change the elements in the default tabs, or get rid of them if they aren't needed. The Ribbon "lives" outside the base forms anyway, and it is essentially a replacement for MENU.MPR. What I have now, is exactly what I wanted. And from what I've seen a much cleaner and simpler way of implementing such a thing that I can make look native compared to the other solutions. Simple is good...

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

(OP)
So after a couple of days, here's where I am with the application. A few quirks to work out as I've migrated to this philosophy, but this is what it looks like:



The only annoyance is the large white space at the top of the form, which I still can't get rid of, which is also a pity because if I enter a caption, then it shows in that bar as well, but without one, the system tray just has the application icon in the tray with a blank name. Small issues, but for the look and feel, I'm pretty stoked.

Thanks to all who have helped with this so far.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

When I set Titlebar=0 in form.init() the white bar at the top is thinner than in your screenshot. It's perhaps just 3 pixel. Your whit spacing on top looks like a full titlebar height. You don't seem to do what I said.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Hi Olaf,
I have it set in the form property Titlebar = 0 - Off.

Also init has the following:

CODE

WITH _SCREEN
	.LOCKSCREEN = .T.
	.Width = 2040
	.Height = 1400
	.CAPTION = ""
	.TITLEBAR = 0
	.LOCKSCREEN = .F.
ENDWITH 

So I agree, it feels like a full height bar, but I am not sure what is "overriding" it.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Well, I said to do it in init and you do. But why on earth are you also setting it at design time? This is making the titlebar NOT disappear and I told you.

In thread184-1777771: VFP Window at Runtime I said:

Quote (myself)

it makes a difference if you try to set Titlebar=0 at design time already, or at runtime. You can set Titlebar=0 in Init and what remains in Windows 10 is a white line a few pixels thick.

This means I said if you set Titlebar=0 at designtime already, you kill the effect of removing the titlebar. Could you please read what's been told to you more thoroughly and pay attention? You seem to always want to do things differently as has been told to you, is that some kind of sport for you?

If I make a test form class with what you do and have both Titlebar=0 at designtime and This.Titlbear=0 in Init(), the titlebar does NOT disappear. This is why your form has the double titlebar, the native one and your own.

All that said it surely deserves a comment about the difference of only setting the property in the class and not in the Init() will NOT work and thus this has to be the way it is and you're not tempted to set the property and remove the code. I for example typically prefer to avoid such code and set properties at designtime. You always have to comment such things, or you keep shooting yourself into your own foot, as you do ever so often.

The reasoning, why it works the one and not the other way can only be accepted - seeing is believing, we don't know what happens behind the scenes. I assume the top-level type overrides the design time setting of no titlebar, so you have to switch this at runtime. And this switch at runtime seems only to have an effect, if it is 1 before, because, well, Windows obviously regards changing from 0 to 0 is no change and means nothing to do. Assumptions. I can't prove them, but the effect is visible and so we don't need to care for proofs, the evidence is visible. Just note one special thing about the titlebar property is its valid values are 0 and 1, not .F. and .T., that hints on it being a property of the Windows C++ TForm base class, that is the basis for the native VFP form class and it's not a VFP property, that would be designed with VFPs values for true and false.

Now I hope this was a detailed enough description, so it gets over.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Ah, I see. Sorry, that subtlety escaped me.
And yeah, this is exactly the kind of "VFP quirk" that makes it so loveable. :)

Thanks, I'm sorry I just missed that comment, and yeah, now it looks just spectacular.
I also discovered some things along the way about OBJTOCLIENT which became very useful in that drop-down scenario with my "flags" on the map. What a handy function! Never new it existed until now, but wow, it is crazy useful when having child forms on top level form, and forms get moved around by users (which happens all the time).

One other odd thing, you see I have that height property at 1400, and width at 2040... the width is right at run time, but the height takes the full top to bottom of screen. Any idea why that would be happening? That code is in the INIT of the Top Level form.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

I don't know your screen resolution, is it higher or lower than 1400 pixels height? I also don't know what you expected, how should I judge your situation, you only tell the half.

If you want fullscreen then I'd use WindowState and if you'd like to make it fullscreen without really being fullscreen, then SYSMETRIC() give you the measurements you need, including size of the taskbar to take into account eventually. Some API also helps finding out where the taskbar is, and whether it is visible. By the way Foxpro only offers a subset of what you may get from Windows API GetSystemMetrics function.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Hi Olaf,
We're using huge screens here, so we DON'T want the top level form to take up the whole space. We just want it to run in about 1600 high x around 2048 wide. (We us 43" 4K monitors, so we've got lots of screen space). So I find it odd that the _SCREEN.WIDTH works fine, but the _SCREEN.HEIGHT is ignored.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Again, _SCREEN is the name of VFPs main form, this is NOT display size, _SCREEN is just a form, not a system monitor/desktop object. You've been told to use Sysmetrics(), because _SCREEN only tells you the desktop dimensions if _SCREEN is a maximized form AND if no taskbar is shown.

Also, you didn't answer my question about your display size. Inches don't matter if we talk about pixels. What's the display resolution?

2048 pixels width would suggest 1536 pixels height in 4:3 aspect ratio, but today's displays will rather have 16:9 aspect ratio, which for 2048 pixels width means 1152 pixels height and then 1400 obviously is too high.

Is it so hard to determine the real resolution of your monitor and program accordingly?

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
I did... I said they are 4K. That resolution is 3840 x 2160
There are 4 of them in this configuration as well, if that makes a difference. So the total desktop screen resolution availble to one application is 7,680 wide x 4320.
I'm keeping the app though, running in the "main display".
The 2048 was based entirely on how much of the width I wanted the application to take up.
I think I see your point about _SCREEN though, so instead set the top level form's height/width properties and it should be ok.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Of course, you set your top-level forms height and width, your form is not _SCREEN just because it is top-level.

In the Init() you can use THIS or THISFORM. (In any form method THIS=THISFORM). _SCREEN is always a separate object, it always exists, but always is not your form. Let me do this for you: Duh. This really hurts.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
LOL. Thanks Olaf, I did not understand this nuance of the _SCREEN object, and explains why I never touched it before as well.
Now I get it. I made the fix in the INIT in the top level form already, and it's all good now. I can see you could probably set _SCREEN.Height = 0 and .Width = 0 and effectively make it invisible, and give it a reference to all other windows of 0,0.

Don't know if that matters much if you have SCREEN = OFF in the Config.FPW anyway.
This Ribbon has been interesting. It's caused me to make a lot of stuff better than it was before, because I hadn't approached it this way previously. Some subtleties involved in dropping MAINMENU.MPR.
It's progressed pretty fast though, and aside from the self-inflicted annoyances, it's gone well. I've tried to model as much behavior in the ribbon as possible from Office. I think the fun part will come when I have to build the "FILE" menu, which in current Office flavor takes over the whole window. So that should be interesting.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Well, why care too much about an object you don't use anyway. SCREEN=OFF means no more and no less than setting _SCREEN.Visible = .T., therefore this VFP "system" form never gets in your way. The reason SCREEN=
OFF is better than _SCREEN.Visible = .F. is that the _SCREEN then really never is visible. You have to know even your first line of code runs after _SCREEN is made visible in the normal case, indeed many things run before your first main.prg or another main file of your project becomes active. And without SCREEN=OFF that means a flicker of _SCREEN shortly visible.

And finally also notice SCREEN=OFF does nto mean _SCREEN is not generated. It will always be there, no matter if you need and use it or not. It doesn't matter, so don't care about _SCREEN at all. Some frameworks you use may use it as publicly available object you can add objects, too. Fpor example gdiplusx adds itself to _SCREEN. So you also better not try to release it or get rid of it in any way.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
For better or worse, I have opted not to use any of the frameworks. So I have focused on building my own instead. Yes, it takes a little longer, but has the benefit of knowing your objects, your control, how they interact. Not saddled with unknown behavior that is obscured by someone else's stuff. I can see why some would go that route, but now today, especially with tool makers essentially vanishing, I'm not stuck with an unmaintainable blob either.
So, I do it the hard way instead, but I think in the long run, it is better. That was even more so confirmed to me when I started looking at Ribbon bar options... they just didn't do what I wanted them to do, they were all "Welcome to 2007 and WindowsXP".

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

Well, gdiplusx is not a framework, but a library, and I think you already use it additonal to foxypreviewer. You know better, but anyway, you shouldn't care about _SCREEN, SCREEN=OFF is all you needed to get it out of the way and have your own top-level form. And that's it. You only would have reasons to learn more about it and act on it, if you'd use it.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Olaf,
Nope, we're not (yet) using gdiplusx or foxypreviewer (We tinkered with it when we were looking at FoxInCloud, but we've since abandoned that approach as well, as it took over and made it the more "important" object, really screwed with our VFP installation, and we had to basically uninstall everything and start over. So I've constantly avoided using these kinds of "solutions" because they just conflict too much with native VFP. I treat VFP largely like I do Excel... everything as native as possible. I only use VBA in Excel when there is NO other way to do what I need otherwise. With VFP I've done the same. I even consider "Shellexec" to be an extravagance because we have to use an API call (same with moving our headerless forms). But there was no other way to do it.

In this case, I'll look for the "most native" way. I can see eventually where we might favor some function of gdiplusx, but for now, we're still full-on native wherever possible.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

(OP)
So I found an interesting trick today to resolve the "peeping icons" issue that I had.
I noticed that if I was on a tab in the ribbon that didn't have any of the large icon container classes that I'm using, there was now icon "show through" when the pageframe is collapsed to 1 pixel. And as I go to those tabs, when they are exposed, and the frame vanishes again, the still show through.
So the interesting sneaky thing I discovered is, I added a blank page to the frame (since the tabs are set to .F. you don't get any "page x" tab). Then when the call to shrink the pageframe comes, I save the current page, then switch to the empty one, roll it up, and no icons poke through. When I click another tab, I swith to that page, open it, display the ribbon as long as they are there, and when leaving roll it up again after switching to the page with 0 controls on it.
So a little kludgy, but it gives the desired outcome, which is cool.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

You posted the solution to a problem you rather discussed in thread184-1777918: PageFrame Trickery.

There I proposed several solutions working with UIEnable etc., but in case of needing no tabs an empty page should have come to mind earlier. I consider it an elegant workaround. Workarounds always are a bit kludgy, but this is a much simpler solution making use of the fact you don't need to care for an additional tab and so it's much more elegant than setting all controls invisible via UIEnable event.

Bye, Olaf.

RE: Building Ribbon Functionality in Application

(OP)
Olaf,
Ah, you are right. Sorry I put this in the wrong thread. But thanks for the kudos, I thought it was interesting enough that it was worth posting back up. Maybe when I get all this working, I'll do an FAQ and how to avoid the gotchas'. I did use the UIEnable idea for something else though, so it too was worth nothing.

Best Regards,
Scott
MIET, MASHRAE, CDCP, CDCS, CDCE, CTDC, CTIA, ATS

"Everything should be made as simple as possible, and no simpler."hammer

RE: Building Ribbon Functionality in Application

I think I know what you meant to say. Thanks, and since the two related threads now are linked by the comment, that's fine for later readers, too.

Bye, Olaf.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close