Author Topic: Right clicks with the Wiimote Whiteboard  (Read 63440 times)

Offline Dan

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #15 on: January 11, 2008, 03:54:25 PM
I don't know much about how the wiimote works, so forgive this if it is dismissible out of hand.  Would putting an additional LED at the back of the pen (run by a thumb switch - as opposed to an index finger switch for the main LED) provide enough distance differentiation to serve as a right click signal?  Is the wiimote color sensitive?

For our app, pen point pressure sensitivity isn't an option (hanging projector screen) and the uses of an additional hand held device won't work (not "sexy").  Plus our CEO has to be able to use it, so we're pretty limited on the ease of use front.

Any merit to this idea?

Thanks to Johnny for a cool project and all of you for your support.
Dan



Offline gabort

  • *
  • Posts: 39
  • Karma: +3/-0
    • View Profile
Reply #16 on: January 12, 2008, 11:51:36 AM
Well, I don't think that would work, if the 2nd. led is on the pen. The pen would normally (naturally) be held at a steep angle to the surface - close to perpendicular, and this could place the blobs close enough to be detected as one. In any case, the position of the sencond light would be a function of the angle of the pen as well, making this quite unpredictable.

Of course, you could have a 2nd. led hang out, perhaps be velcro-ed to the forearm of the speaker, but that does not sound too cool either. The pen would also be awkward, in my oppinion, if two switches would be attached to it.

Furthermore, how would you tell the software, which is the "cursor blob" from the tip of the pen, and which is only lit because you want a right-click? Since we do not have colors, a blob is a blob, so the one that lights up first will be the "cursor blob"...

I find a lot more merit in the idea (coincidentally my own) to have a second separate switch that signals clicks, and use the pen only to move the cursor around. The soon to be available wireless nunchuck is a natural solution in my oppinion, and I'll give it a go too, as soon as I can get my claws on one.



Offline atomriot

  • *
  • Posts: 177
  • Karma: +16/-0
    • View Profile
Reply #17 on: January 12, 2008, 08:43:37 PM
ok, what about this, idea number 2 from me.


this is my altered whiteboard app


what the black box is, is the tracking box from the standard lib app. the red and green blobs indicate 2 different IR points. the green blob indicates the a point at RawMidX and RawMidY and is only drawn when (ws.IRState.Found1 && ws.IRState.Found2) which means 2 points

now where i am going with this is what if you had 2 pens or a pen and another IR source. if the point (RawMidX, RawMidY) were greater than say 20% of the distance of the screen you are working with apart, so for 1024x768 the distance between the 2 points is greater than 200 pixels) then it would initiate a right click.

the reason for the distinguishing if they are so far apart it because if they are too close, then it looks like 1 IR source. so you could have a pen or source in each hand.

not real classy sure, but its an easy idea to implement.

alternatively, in the project ideas section i described an idea for an app that does it backwards. wiimote in hand and a stationary IR LED. or multiple LEDs depending on the need of the application.

Details, details. Things to do. Things to get done. Don't bother me with details, just tell me when they're done.
--
James Lionel Price



Offline weck9406

  • *
  • Posts: 10
  • Karma: +1/-0
    • View Profile
Reply #18 on: January 13, 2008, 12:01:15 AM
I am in agreement with the camp that says to have 2 IR LEDs on one pen would end up looking like a single light.  Even if you were to angle them, I don't think you could get enough separation to distinguish 2 separate blobs.  But let's say, theoretically, that you could get the IR LEDs to direct their light such that you could get this 20% separation at a given distance away from the IR sensor.  You could potentially go further away that this distance, but you could not come closer since your separation would decrees to less that 20%.  At any angle, the further away you are from the source, the further the distance the projections would be from each other at the target.  The closer you are the closer the projections are to each other.  This would limit the usabilty to a given distance.

I know it is neat to have these theoretical discussions and try to find new and creative ways to do thing to try to circumvent the laws of physics and mathematics, but it is always best to keep things simple.  When you have tools at your disposal that can do the job (a second Wii controller connected via Bluetooth or the new wireless nunchuck) that aren't restricted by the problems faced using a sencond LED, why not use them?




Offline gabort

  • *
  • Posts: 39
  • Karma: +3/-0
    • View Profile
Reply #19 on: January 13, 2008, 12:59:21 PM
Hey atomriot, I noticed you have one more nice feature on this app of yours... how does the "all available screens" radio button work? (I have a double-screen setup too :) )

Care to share the app later on?



Offline atomriot

  • *
  • Posts: 177
  • Karma: +16/-0
    • View Profile
Reply #20 on: January 13, 2008, 03:30:40 PM
oh yeah, i had to add that because we commonly just extend our desktop for our conference room and it initially only worked with the default screen.
this is my calibration form constructor from CalibrationFrom.cs
Code: [Select]
        public frmCalibration(bool useThis,int left,int top)
        {
            [color=red]this.Location = new Point(left, top);
           
            Rectangle rect = new Rectangle();
            Screen[] allScreens = Screen.AllScreens;
            int x = left;
            int y = top;
            int width = 0;
            int height = 0;
            if (Screen.AllScreens.Length > 1 && !useThis)
            {
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.X < x)
                        x = screen.Bounds.X;
                    if (screen.Bounds.Y < y)
                        y = screen.Bounds.Y;
                    if (screen.Bounds.Right > width)
                        width = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > height)
                        height = screen.Bounds.Bottom;
                }
                rect = new Rectangle(x, y, width, height);
            }
            else
            {
                rect = Screen.GetBounds(new Point(left+1,top+1));
            }[/color]

            InitializeComponent();
            this.FormBorderStyle = FormBorderStyle.None;
            this.Left = rect.Left;
            this.Top = rect.Top;
            this.Size = new Size(rect.Width, rect.Height);
            this.Text = "Calibration - Working area:" + Screen.GetWorkingArea(this).ToString() + " || Real area: " + Screen.GetBounds(this).ToString();

            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyPress);

           
            screenHeight = rect.Height;
            screenWidth = rect.Width;

            bCalibration = new Bitmap(screenWidth, screenHeight, PixelFormat.Format24bppRgb);
            gCalibration = Graphics.FromImage(bCalibration);
            pbCalibrate.Left = 0;
            pbCalibrate.Top = 0;
            pbCalibrate.Size = new Size(rect.Width, rect.Height);
           
            gCalibration.Clear(Color.White);

            BeginInvoke((MethodInvoker)delegate() { pbCalibrate.Image = bCalibration; });
        }

the changed part is pretty much everything before the InitializeComponent(); line.

this is my main form constructor

Code: [Select]
public frmMain()
{
            CheckForIllegalCrossThreadCalls = false;
            screenWidth = Screen.GetBounds(this).Width;
            screenHeight = Screen.GetBounds(this).Height;
            screenTop = Screen.GetBounds(this).Top;
            screenLeft = Screen.GetBounds(this).Left;

            if (Screen.AllScreens.Length > 1)
            {
                Screen[] allScreens = Screen.AllScreens;
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.Right > screenWidth)
                        screenWidth = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > screenHeight)
                        screenHeight = screen.Bounds.Bottom;
                    if (screen.Bounds.Top < screenTop)
                        screenTop = screen.Bounds.Top;
                    if (screen.Bounds.Left < screenLeft)
                        screenLeft = screen.Bounds.Left;
                }
            }
            InitializeComponent();
            CanCalibrate = true;
}

and then i have the methods that handle checking if those radio buttons are selected

Code: [Select]
        private void btnCalibrate_Click(object sender, EventArgs e)
        {
            if (CanCalibrate)
            {
                if (cf == null)
                {
                    if (rdoBtnCurrent.Checked)
                    {
                        cf = new frmCalibration(true, Screen.GetBounds(this).Left, Screen.GetBounds(this).Top);
                    }
                    else
                    {
                        cf = new frmCalibration(false,0,0);
                    }
                    cf.Show();
                }
                if (cf.IsDisposed)
                {
                    if (rdoBtnCurrent.Checked)
                    {
                        cf = new frmCalibration(true, Screen.GetBounds(this).Left, Screen.GetBounds(this).Top);
                    }
                    else
                    {
                        cf = new frmCalibration(false,0,0);
                    }
                    cf.Show();
                }
                calibrationState = 1;
                doCalibration();
            }
        }

        private void Screens_CheckedChanged(object sender, EventArgs e)
        {
            screenWidth = Screen.GetBounds(this).Width;
            screenHeight = Screen.GetBounds(this).Height;
            screenTop = Screen.GetBounds(this).Top;
            screenLeft = Screen.GetBounds(this).Left;

            if (Screen.AllScreens.Length > 1 && !rdoBtnCurrent.Checked)
            {
                Screen[] allScreens = Screen.AllScreens;
                foreach (Screen screen in allScreens)
                {
                    if (screen.Bounds.Right > screenWidth)
                        screenWidth = screen.Bounds.Right;
                    if (screen.Bounds.Bottom > screenHeight)
                        screenHeight = screen.Bounds.Bottom;
                    if (screen.Bounds.Top < screenTop)
                        screenTop = screen.Bounds.Top;
                    if (screen.Bounds.Left < screenLeft)
                        screenLeft = screen.Bounds.Left;
                }
            }
        }


you also have to adjust the calling of the calibration

Code: [Select]
        public void doCalibration(){
            if (cf == null)
                return;
            int x = screenLeft;
            int y = screenTop;
            int size = 25;
            Pen p = new Pen(Color.Red);
            int crossX = 0;
            int crossY = 0;
            switch (calibrationState)
            {
                case 1:
                    crossX = (int)(screenWidth * calibrationMargin);
                    crossY = (int)(screenHeight * calibrationMargin);
                    x += (int)(screenWidth * calibrationMargin);
                    y += (int)(screenHeight * calibrationMargin);

                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 2:
                    crossX = screenWidth - (int)(screenWidth * calibrationMargin);
                    crossY = (int)(screenHeight * calibrationMargin);
                    x += screenWidth - (int)(screenWidth * calibrationMargin);
                    y += (int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 3:
                    crossX = (int)(screenWidth * calibrationMargin);
                    crossY = screenHeight - (int)(screenHeight * calibrationMargin);
                    x += (int)(screenWidth * calibrationMargin);
                    y += screenHeight -(int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;
                case 4:
                    crossX = screenWidth - (int)(screenWidth * calibrationMargin);
                    crossY = screenHeight - (int)(screenHeight * calibrationMargin);
                    x += screenWidth - (int)(screenWidth * calibrationMargin);
                    y += screenHeight -(int)(screenHeight * calibrationMargin);
                    cf.showCalibration(crossX, crossY, size, p);
                    dstX[calibrationState - 1] = x;
                    dstY[calibrationState - 1] = y;
                    break;

everything after this in the DoCalibration() method is default. so dont just replace that entire method because then you wont get the case 5 or default

thats pretty much it. basically it should check which screen it is using. you have to pass a bool into the calibration form to tell it to use multiples or not.

hopefully this works for you, i might have left something else out but if so then let me know. it was fun to figure out and is definitely worth digging through the code because it gives you a better understanding of it.

once i get the project done and cleaned up, perhaps it can be put up on the download section as a supplemental project. I could not have gotten this far without Johnny's work, thats for sure.

Details, details. Things to do. Things to get done. Don't bother me with details, just tell me when they're done.
--
James Lionel Price



Offline gabort

  • *
  • Posts: 39
  • Karma: +3/-0
    • View Profile
Reply #21 on: January 14, 2008, 07:05:11 AM
Thanks for posting!



Offline troy59

  • *
  • Posts: 123
  • Karma: +2/-0
    • View Profile
Reply #22 on: January 14, 2008, 01:16:30 PM
i'm not quite sure i understand this, but if i understand what you were saying, you need 3 other IR's to tell the wiimote to right click? If that is so, then you could have the pen in one hand, then a glove on the other with and IR led on the back of a finger. Gloves look cool and futuristic if made right, and y 3, you could just as well use 1 other IR if it was far enough away for the wii mot to distinguish inbetween the two dots, If you had the glove with the led on the back, you just make a swith on, say, your pointer finger, you could even make a switch out of tin foil and two pieces of wire. So, basically, you have a glove with a led on the back of it, and your pen in the other hand, then when you activate the led on your hand, the wii remote will see it and make a right click.



Offline atomriot

  • *
  • Posts: 177
  • Karma: +16/-0
    • View Profile
Reply #23 on: January 14, 2008, 01:46:12 PM
if your are talking about my 3 IR source idea, i say that with the assumption that the primary source is not actually clicking the mouse. you have one source that just moves it, then others that handle clicks. this could be narrowed to just two if you light pen does the clicking and moving at the same time.

Details, details. Things to do. Things to get done. Don't bother me with details, just tell me when they're done.
--
James Lionel Price



Offline bryanarby

  • *
  • Posts: 89
  • Karma: +2/-1
    • View Profile
Reply #24 on: January 14, 2008, 01:53:08 PM
As posted in here: http://www.wiimoteproject.com/project-ideas/non-drag-and-drop-mouse-with-lmb-and-rmb-t128.0.html

this could give the solution when using Wiipens (that's how I named em/I refer to em) on USB feed. By using micro controllers pics to "create" the mouse click signal you would get a extreme flexible Wiipen.
Pro: having more functions.
Con: the size of pen will increase /w each extra function.
I'll try and get the data round up before friday, saturday tweak time, monday is next test day.
Data needed: the signals for Left and right mouse button, hook em up to a osciloscope on paths D- and D+.
For info about what is what on usb cable:
http://pinouts.ru/Slots/USB_pinout.shtml
« Last Edit: January 15, 2008, 09:50:49 AM by bryanarby »

wiipen
point ATM: building V2
V1: 1 LED on 1 AAA battery feed
V2: 1 LED on USB feed
V2 will be remodded too V3
V3: 1 LED on USB feed /w LMB and RMB
V4: 1 LED WIRELESS /w LMB and RMB
V5: we'll see :3
Vmany: Bluetooth IR pen with mouse functions.


Offline thesilentpyro

  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Reply #25 on: January 15, 2008, 09:22:27 AM
I think some people here are missing a few facts (not to put anything down, I'd just like to point some things out).  One: Multiple LEDS on a pen is not a very feasible idea; there are too many variables the software cannot account for--namely, angle.  Angle the pen is held if there is an LED on the back.  Angle the Wiimote is viewing the plane from.  Angle of the user's arm.  Angle of rotation of the pen if the LEDs are at the tip.  Too much.  Two: Three selling major points of this project are simplicity, portability, and low-cost; the original project really only require a Wiimote and a <$6 LED pen that is assembled relatively easily.  Meets all the points.  Microcontrollers, additional peripherals, corded controllers, things in the off-hand--all these infringe on the selling points.  Three: People are stupid.  Granted, if they can get this project to work, they're undoubtedly on the upper half of the bell curve, but you cannot give people too many things to do and expect them to do it all correctly.

Personally, I'm an advocate of software-driven right-click.  The "click area" idea is a feasible one I think--if you want an "always on" cursor, get a second pen and use the multipoint capabilities to have one hand controlling the mouse and the other clicking.  I also really liked the timed-click aspect; that is how older Macs worked with popping up alternate menus, and that survived pretty well for a while.  The system, which I imagine wouldn't be very hard to implement since we already have mouse-emulation in effect, is that if the pen is moving, it's a click-and-drag.  If it's stationary and only appears for a short time, say under two seconds, it's a left-click.  If it's stationary and appears for more than two seconds, it's a right-click.  I know it's not ideal for a lot of things, including most games, but let's face it; the whole interface is not ideal for most games.



Offline bryanarby

  • *
  • Posts: 89
  • Karma: +2/-1
    • View Profile
Reply #26 on: January 15, 2008, 09:54:40 AM
Two: Three selling major points of this project are simplicity, portability, and low-cost; the original project really only require a Wiimote and a <$6 LED pen that is assembled relatively easily.  Meets all the points.  Microcontrollers, additional peripherals, corded controllers, things in the off-hand--all these infringe on the selling points.  Three: People are stupid.  Granted, if they can get this project to work, they're undoubtedly on the upper half of the bell curve, but you cannot give people too many things to do and expect them to do it all correctly.

well 1 I dont disagree.., 2: cheapest pic is less then one euro..,3 Thats why there should become pre-made pens available and some sort of manual ^^

wiipen
point ATM: building V2
V1: 1 LED on 1 AAA battery feed
V2: 1 LED on USB feed
V2 will be remodded too V3
V3: 1 LED on USB feed /w LMB and RMB
V4: 1 LED WIRELESS /w LMB and RMB
V5: we'll see :3
Vmany: Bluetooth IR pen with mouse functions.


Offline troy59

  • *
  • Posts: 123
  • Karma: +2/-0
    • View Profile
Reply #27 on: January 15, 2008, 10:28:42 AM
1. I agree you should use it like the macs button(they still use it) 2. Its very simple to make, but you could manufacture a $5 pen 3. Most average people are pretty stupid, they don't even know what a usb is, so a manual would help the average human being would need one, i know my dad is stuborn enough to use one, "they put them in here for a reason"



Offline The Rick

  • *
  • Posts: 7
  • Karma: +0/-0
    • View Profile
Reply #28 on: January 15, 2008, 12:18:54 PM
I had an idea for a right click that I thought up while using my phone the older day.  In order to utilize a right-click with the stylus, you pressed onto the screen until a series of lights lit up, then the right-click menu appeared.  Could some code be created that runs either simultaneously, or even built in, with the WiiMote Whiteboard software, that utilizes this functionality?

This way, you can still click and drag around to highlight or move windows, but if held in place, it brings up the light sequence to activate the right-click menu (or action)?



Offline bryanarby

  • *
  • Posts: 89
  • Karma: +2/-1
    • View Profile
Reply #29 on: January 15, 2008, 12:56:05 PM
well the point and hold is what mac idea is about ^^

wiipen
point ATM: building V2
V1: 1 LED on 1 AAA battery feed
V2: 1 LED on USB feed
V2 will be remodded too V3
V3: 1 LED on USB feed /w LMB and RMB
V4: 1 LED WIRELESS /w LMB and RMB
V5: we'll see :3
Vmany: Bluetooth IR pen with mouse functions.