SFML community forums

Help => Window => Topic started by: vurentjie on June 25, 2008, 02:13:40 am

Title: mouse coord out until resize by any amount
Post by: vurentjie on June 25, 2008, 02:13:40 am
hi, i tried to simplify my code as much as possible and extract exactly where my problem is occuring, so the code below if copied and pasted wil compile, i have just included the neccessary pieces from multiple files where i have found a problem,

the problem, i set my window as a desktop_mode, then i draw a 2dpanel at the bottom of the viewport that overlays the 3d viewport, if the mouse cursor is over the black 'drag-line' and left mouse is held down, the panel can be resized/dragged up and down,

there could be a problem in my code, but from tests i am guessing something else, if i load the program up and without resizing i try to drag the panel, it misses the mark by about 20px, as soon as i resize by any amount it behaves as it should, the code shouldn't be wrong as i have used it before, but i might be wrong,please check for me,you can just copy paste code....

sorry if it is a bit long but i have tried to preserve exactly how i use it,not usually in one file though

Code: [Select]

#include <SFML/Window.h>
#include<SFML/System.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct GUI{

   int high, wide;
}GUI;


GUI *mygui;
int init_gui_panel(int w, int h, GUI *gui);
void guidraw();

sfEvent Event;
sfWindow* mywin;

enum   actions {DRAGS, NONE};

static int action = NONE;



void guidraw(){

      glColor3f(0.1,0.1,0.1);
     glBegin(GL_QUADS);
        glVertex2i(mygui->wide, (mygui->high-5));
        glVertex2i(0,(mygui->high-5));
        glVertex2i(0, mygui->high);
        glVertex2i(mygui->wide, mygui->high);

     glColor3f(0.7,0.7,0.7);
        glVertex2i(mygui->wide, 0);
        glVertex2i(0,0);
        glVertex2i(0, (mygui->high-5));
        glVertex2i(mygui->wide, (mygui->high-5));
        glEnd();

}






int init_gui_panel(int w, int h, GUI *gui){

    //this function should encapsulate more than this later!!

   gui->high = (h/4);
   gui->wide = w;

   return gui;

}


int main(){

    sfWindow* mywin;
    sfWindowSettings Settings = {24,8,4};
    mywin = sfWindow_Create(sfVideoMode_GetDesktopMode(), "Quirk", sfResize | sfClose, Settings);


    GUI initgui;
    mygui = init_gui_panel(sfWindow_GetWidth(mywin), sfWindow_GetHeight(mywin),&initgui);

while(sfWindow_IsOpened(mywin)){
const sfInput* input = sfWindow_GetInput(mywin);

     if(sfWindow_GetEvent(mywin, &Event)){

             switch(Event.Type)
             {
                 case sfEvtClosed:
                      sfWindow_Close(mywin);
                 break;

                 case sfEvtMouseButtonPressed:
                    switch(Event.MouseButton.Button){

                        case sfButtonLeft:
                        if( (sfInput_GetMouseY(input) > sfWindow_GetHeight(mywin)-mygui->high)  &&     (  sfInput_GetMouseY(input) < sfWindow_GetHeight(mywin)-mygui->high+5)  ){

                            action=DRAGS;
                        }
                        break;
                    }
                 break;


                 case sfEvtMouseButtonReleased:
                    if( Event.MouseButton.Button == sfButtonLeft)
                        {
                        action = NONE;
                        }
                 break;

                 case sfEvtMouseMoved:

                      switch(action){
                       case DRAGS:
                            mygui->high = (sfWindow_GetHeight(mywin)-(Event.MouseMove.Y));

                            if( ((sfWindow_GetHeight(mywin)-Event.MouseMove.Y) > (sfWindow_GetHeight(mywin)-30)) )
                            {
                            mygui->high = (sfWindow_GetHeight(mywin)-30);
                            }

                            if( Event.MouseMove.Y > (sfWindow_GetHeight(mywin)-30))
                            {
                            mygui->high = 30;
                            }
                            break;
                      }
                 break;

             }
     }

     sfWindow_SetActive(mywin, 1);

     glClearColor(0.5,0.5,0.5,1.0);
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


     //3d
     float aspect;
        aspect = ((float)sfWindow_GetWidth(mywin))/((float)sfWindow_GetHeight(mywin));
        glViewport(0,0,sfWindow_GetWidth(mywin), sfWindow_GetHeight(mywin));
        glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluPerspective(45.0, aspect, 0.1, 200.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();





     //2d
     glMatrixMode (GL_PROJECTION);
        glLoadIdentity ();
        gluOrtho2D(0, sfWindow_GetWidth(mywin), 0, sfWindow_GetHeight(mywin));
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

    guidraw();



     sfWindow_Display(mywin);

 }




    return 0;
}






help appreciated
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 25, 2008, 10:22:17 am
ok, no reply??mmm....maybe i shouldnt have pasted all that code, well i am not asking it to be fixed if it is wrong on my part. but later today i will try post an even simpler example of what i mean,


oh and by resize i mean resize the window,
if i load the window with getdesktop and i try adjust the panel (that i draw in opengl) it wont work, if i just adjust the window size by even 1px i can now adjust the panel by click-and-hold on it's drag-line...

this is on windowsxp, sfml 1.3, i am going to test it on 1.2 and check if it does same thing..

but as i say i have used this code before....except for the getdesktopmode part.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 25, 2008, 01:59:43 pm
ok after double checking this,

if instead of
Code: [Select]

    sfWindow* mywin;    
    sfWindowSettings Settings = {24,8,4};
    mywin = sfWindow_Create(sfVideoMode_GetDesktopMode(), "Quirk", sfResize | sfClose, Settings);


i use say,

Code: [Select]

    sfWindow* mywin;
    sfVideoMode Mode = {800, 600, 32};
    sfWindowSettings Settings = {24,8,4};
    mywin = sfWindow_Create(Mode, "Quirk", sfResize | sfClose, Settings);


then my mouse input records just fine without having to resize the window,


which leads me to ask, is there something wrong how i am calling sfVideoMode_GetDesktopMode()?? or is it something else??
Title: mouse coord out until resize by any amount
Post by: Laurent on June 25, 2008, 02:33:34 pm
I can't see any relation between the video mode and the inputs, I'll try this code and see if I can reproduce the problem.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 25, 2008, 03:03:44 pm
cool thanks, sorry for the hassle, if you notice anything blatantly wrong in my code just let me know, i don't need a full solution, maybe just a tip,

i don't think this should matter, but i build in code::blocks...
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 25, 2008, 08:21:42 pm
earlier you said you don't see relation between video mode and input, i think there might be,you know this but just to recap

mouse-y starts at top=(0)

opengl-y starts at bottom=(0)

if i draw a simple line across the screen in opengl using orthographic 192px  from bottom,

and i everytime i click mouse on the line and print out -> window-height,  mouse-ypos (from top),   line-height(from bottom),

these are results:

open as desktop mode, no resize just one click on line,
window height  768
mouse y from top 556
line height from bottom  192
windowheight  minus  mousey gives 212 (20px out  - possibly taskbar)


open as desktop mode, maximize,  just one click on line,
window height  708
mouse y from top 508
line height from bottom  192
windowheight  minus  mousey gives 202 (10px out ?)

open as desktop mode, drag windows left edge slightly inward,  just one click on line,
window height  742
mouse y from top 548 (-edit:550)
line height from bottom  192
windowheight  minus  mousey gives 192 -----CORRECT



open as 800X600, no resize,  just one click on line,
window height  600
mouse y from top 408
line height from bottom  192
windowheight  minus  mousey gives 192 -----CORRECT


have you tried this?
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 26, 2008, 11:07:48 am
hi,

i dont know if you had time to look at this, if you did could you pls inform me if you encountered same thing.
it is not a serious issue for me at the moment in any case,

later
Title: mouse coord out until resize by any amount
Post by: Laurent on June 26, 2008, 11:16:54 am
Yes of course, I'll check this as soon as possible and let you know if I can find something ;)
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 26, 2008, 08:00:05 pm
hi,

i had a look through the svn and downloaded some of the source for window and video, i think i am going to have to download the c++ source, and i am going to see if i can try help debug this - or at least find out if it is a code bug or my display or something, at least to teach myself a bit more about what is going on behind the scenes,  
I had a look at the msdn DEVMODE docs, and will start from there and then go through the window creation, even if i dont come up with a solution I will definitely gain from trying, later.....
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 12:40:48 am
ok i got a build workspace up and running, can compile the c++ and c libs, i am going to try check this out,

i have been thinkin though, i understand that you use dmPelsHeight to detect the height of the screen, is this connect in anyway to anything else,

would it not be possible to use GetSystemMetrics( SM_CYFULLSCREEN ), but i am not actually sure if that is where the problem lies in any case but it is where i am first going to start.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 01:13:19 am
i just want to ask a quick question,

this is the first time i am trying something like this so kinda in the deep end here,

if i want to make changes that are reflected in the csfml libs,

i first make changes to the c++ source, compile those libs,

and then compile the c libs, correct?
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 02:25:23 am
okay i managed to get things going and want to discuss,

i changed return value of getdesktopmode to this:

   
Code: [Select]

 return VideoMode(GetSystemMetrics( SM_CXFULLSCREEN ), GetSystemMetrics( SM_CYFULLSCREEN ), Win32Mode.dmBitsPerPel);


what this does is give the correct input from mouse, however the screenposition is now 20px lower.

I think dmPelsHeight was getting stuck somewhere on my system, and don't know exactly why, I was guessing my display drivers or monitor (HP 7540) doesnt agree with the DEVMODE stuff

i am going to try SM_CYSCREEN, as SM_CYFULLSCREEN, takes into account the bottom taskbar on windows, I think this will resolve the issue, but not sure how it affects videomode, although I pretty sure nothing bad will come of it.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 02:32:51 am
i tried CYSCREEN instead, now this is exactly where mouse input becomes 20px out, as the screen size is perfectly set as a fullscreen desktop but mouse input is out by 20px (repeating myself here)....which means i am wrong about the DEVMODE stuff, that is all fine, the problem possibly lies either in the positioning on the screen, or in the actual input capture, not quite sure, going to go check that out now.
Title: mouse coord out until resize by any amount
Post by: Laurent on June 27, 2008, 02:58:59 am
Hey, thanks a lot for trying to solve it by yourself :)

I'm sorry I don't have much time to help you right now, but I'll try to check it this week-end.

Let me know if you find more :)
Title: mouse coord out until resize by any amount
Post by: Wizzard on June 27, 2008, 03:29:52 am
You could try getting the dimensions of the viewport rather than the window. I have no clue if this'll give you the results you want, but it's worth a try.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 04:01:51 am
cool, no luck yet, i am going to look at it this weekend too, i havent made a win32 window in a long time so having to relearn a whole bunch in the process, but i guess it will give me some hair on my chest,

i am actually enjoying the challenge, and hope to solve it, i got a nifty program called source navigator which is helping me stacks to jump around in your code...till anon
Title: mouse coord out until resize by any amount
Post by: SirJulio on June 27, 2008, 04:18:23 am
Hi,

I think i found the problem.

When SFML trying to create a window with a client area egal to screen resolution (or highest), then, resulting client area is smallest than the requested VideoMode (maybe title bar size). ATM, SFML width and height are initialized before any window creation, and not updated after that :

Code: [Select]
// LoC 145 (WindowImplWin32.cpp)
    int Width  = myWidth  = Mode.Width;
    int Height = myHeight = Mode.Height;


If the client area of the windows is smaller than the requested video mode (if you pass GetDesktopMode(), it will be) window GetHeigth and GetWidth will be false until a WM_SIZE notif (which will call GetClientRect).

This could be fix with a GetClientRect call after the window creation :

Code: [Select]
LoC 171 WindowImplWin32.cpp
    // Create the window
    if (HasUnicodeSupport())
    {
        wchar_t WTitle[256];
        int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
        WTitle[NbChars] = L'\0';
        myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }
    else
    {
        myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }

// ==== NEW ====
    if (!Fullscreen)
    {
        RECT clientRect = {0, 0, 0, 0};
        if (!GetClientRect(myHandle, &clientRect))
        {
            // ...
        }
        myWidth = clientRect.right - clientRect.left;
        myHeight = clientRect.bottom - clientRect.top;
    }
// ==== /NEW ====


I don't know how openGL context creation is influenced by this modification, but the OP code works perfectly with it (in all resolution, fulscreen etc).
Title: mouse coord out until resize by any amount
Post by: Laurent on June 27, 2008, 05:10:05 am
The client area always matches the requested mode :
Code: [Select]
WindowImplWin32.cpp

  163     if (!Fullscreen)
  164     {
  165         RECT Rect = {0, 0, Width, Height};
  166         AdjustWindowRect(&Rect, Win32Style, false);
  167         Width  = Rect.right - Rect.left;
  168         Height = Rect.bottom - Rect.top;
  169     }

So it shouldn't be necessary to get the client size after creation :|
Title: mouse coord out until resize by any amount
Post by: SirJulio on June 27, 2008, 05:55:53 am
Yeap you're right, it shouldn't =p

e.g. i use 1280x1024, with getDesktopMode VideoMode is at 1280x1024, and Rect from AdjustRect is at 1288x1058 (window area) but the final window size (include border and title) is 1288x1036. That's why your final client area is shrinked (requested : 1280x1024 real : 1280x1002).

Some tests with differents window size :

Code: [Select]
   // Create the window
    if (HasUnicodeSupport())
    {
        wchar_t WTitle[256];
        int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
        WTitle[NbChars] = L'\0';
        myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }
    else
    {
        myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }

    {
        if (!Fullscreen)
        {
            RECT clientRect , windowRect = {0, 0, 0, 0};
            GetClientRect(myHandle, &clientRect);
            GetWindowRect(myHandle, &windowRect);
            myWidth = clientRect.right - clientRect.left;
            myHeight = clientRect.bottom - clientRect.top;
            int realWidth = windowRect.right - windowRect.left;
            int realHeight = windowRect.bottom - windowRect.top;
            std::cout << "Requested client : " << Mode.Width << "x" << Mode.Height << " Real client : " << myWidth << "x" << myHeight << std::endl;
            std::cout << "Requested window : " << Width << "x" << Height << " Real client : " << realWidth << "x" << realHeight << std::endl;

        }
    }


800x600 (OK) :
Quote
Requested client : 800x600 Real client : 800x600
Requested window : 808x634 Real client : 808x634


1024x768 (OK) :
Quote
Requested client : 1024x768 Real client : 1024x768
Requested window : 1032x802 Real client : 1032x802


1280x1024 (desktop resolution) :
Quote
Requested client : 1280x1024 Real client : 1280x1002
Requested window : 1288x1058 Real client : 1288x1036


1280x1024 (with sfNone instead of sfResize | sfClose)
Quote
Requested client : 1280x1024 Real client : 1280x1024
Requested window : 1280x1024 Real client : 1280x1024

I don't know why CreateWindow reduce your window size (maybe there is a maximum window size ?) but it does. =)
Title: mouse coord out until resize by any amount
Post by: Laurent on June 27, 2008, 06:11:50 am
Damn, I have to find out what's going on. Probably some OS internal magic... :|
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 27, 2008, 02:03:13 pm
yeah i also noticed that, that the screen dimension that i print out shrinks  when i resize, even though the height has not changed at all, but been at work the whole day, going to look more at it this weekend, one of us is going to solve this soon as it is not many files to deal with.


edit-->add

also thanks SirJulio, that definitely seems to be where the problem lies, at first i thought it might be something just with getdesktop, but if i do something like the following


Code: [Select]

sfVideoMode Mode = {GetSystemMetrics( SM_CXSCREEN )-x, GetSystemMetrics( SM_CYSCREEN )-x, 32};


and i start x at 0, and increment, only when x reaches 25 will my screen and input behave.
Title: mouse coord out until resize by any amount
Post by: SirJulio on June 27, 2008, 03:24:50 pm
Yeap, i think we have our problems too.

I made some tests with wininspector and apparently on my comp, 1292x1036 seems to be the larger size I can use for any window (notepad for the test). This values is exactly what GetSystemMetricsSM_C[X|Y]MAXTRACK) returns. After some querying, Caption bar vertical size of sizable window is 26 (SM_CYCAPTION), and border of the window is 4 (SM_CYBORDER), so we found our magical number. Window cannot be higher than 1036 (always on my res : 1024) and for sizable window we must count caption and border size (26 + 2 * 4 = 34), so we cannot have a client area higher than 1002 (1036 - 34), which is equivalent to prior results. If your window is created with sfNone (noborder no caption), you don't have the problem because resulting window will be at the correct size (no need to count border and caption).

According to MSDN, you can override this behavior by processing WM_GETMINMAXINFO (http://msdn.microsoft.com/en-us/library/ms632626(VS.85).aspx) notif.

But, IMHO, creating a window higher than the screen vertical resolution (which seems possible) is not a good thing, dev request a VideoMode, but uses GetWidth and GetHeight to keep all calculs relative. If GetDesketopMode, create a client area smaller than the requested one, this is not a problem but GetWidth and GetHeigth return by Window must be correct.

So, i think that "post-calculate" the real Width and Height would be the best methods for this kind of situation. =)
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 28, 2008, 02:58:18 am
ok i have come up with a solution will post it now, actually very very simple!

just need to add check for fullscreen mode.as the problem was just calculate interior render window.
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 28, 2008, 03:12:50 am
ok here we go this was the only part i needed to change,

Code: [Select]

////////////////////////////////////////////////////////////
/// Create the window implementation
////////////////////////////////////////////////////////////
WindowImplWin32::WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params) :
myHandle          (NULL),
myCallback        (0),
myCursor          (NULL),
myKeyRepeatEnabled(true)
{
    // Register the window class at first call
    if (ourWindowCount == 0)
        RegisterWindowClass();

//    changes here
    int Left   = (GetDeviceCaps(GetDC(NULL), HORZRES) - Mode.Width)  / 2;
    int Top    = (GetDeviceCaps(GetDC(NULL), VERTRES) - Mode.Height) / 2;

    //first calculate outer dimension
    int Width  = Mode.Width;
    int Height = Mode.Height;


//  
    //then calculate dimensions of render view
    myWidth  = Width - (2*GetSystemMetrics( SM_CXSIZEFRAME ));
    myHeight = Height - (2*GetSystemMetrics( SM_CYSIZEFRAME )) - GetSystemMetrics( SM_CYCAPTION );


    // Choose the window style according to the Style parameter
    DWORD Win32Style = WS_VISIBLE;
    if (WindowStyle == Style::None)
    {
        Win32Style |= WS_POPUP;
    }
    else
    {
        if (WindowStyle & Style::Titlebar) Win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
        if (WindowStyle & Style::Resize)   Win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
        if (WindowStyle & Style::Close)    Win32Style |= WS_SYSMENU;
    }

    // In windowed mode, adjust width and height so that window will have the requested client area
    bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
    /*  if (!Fullscreen)
    REMOVED THIS AND OPTED FOR TOP AS IT WAS THROWING OUT, I THINK,EITHER WAY NOT NEEDED
    */

    // Create the window
    if (HasUnicodeSupport())
    {
        wchar_t WTitle[256];
        int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
        WTitle[NbChars] = L'\0';
        myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }
    else
    {
        myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
    }




i checked the resize event and that is fine, and is the only other place that i could see that myWidth/myHeight was being changed,
also checked fullscreen mode and seemed to work just fine,


later.
Title: mouse coord out until resize by any amount
Post by: Laurent on June 28, 2008, 11:15:10 am
Ok I see. I've changed the code so that now the window's client size is calculated again after its creation.

vurentjie, I don't think your idea of calculating manually the window's external size was the way to go, especially if you don't take the style in account. Anyway it was also more complicated than just recomputing the size after creation ;)

Thank you guys for your help, let me know if everything's fine now or not :)
Title: mouse coord out until resize by any amount
Post by: vurentjie on June 28, 2008, 10:26:22 pm
cool no worry, i will grab the updates, was merely what i came up with in the situation, and worked, but thanks.