how to tell how long a button is pressed

  • Thread starter Thread starter pantherteeth
  • Start date Start date
P

pantherteeth

I'm writing a little mp3 player shell type thing, and I'm trying to
figure out how to determine how long a button has been pressed.

For example, if a user clicks the left button, the song should be
decremented to the previous one. However, if the user holds the button
down for two seconds, the song would begin rewinding. Further, if the
button is pressed for five seconds, the folder will change to a
previous one.... and so on.

I can't find anywhere that says how to do this. Any suggestions?
 
Is that really intuitive? How the heck would the user
know why certain actions are taking place? They'd
have no clue how long the button was down or
why it was triggering an action.

You'd get an F grade from our usability team...
 
i disagree. many traditional cassette and CD players worked this way, a
single press on the button for a whole song rewind, hold down for
continuous rewind.

i have written the following code to simulate the functionality you
describe. the progress bar is supposed to represent the song progress :)
you can click rewind and if you let up before 150ms (the Timer length), it
does a full song rewind. otherwise it assumes you intend to do a continuous
rewind.

hope this helps your app.
tim

using System;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
using System.Web;

namespace Test
{


public class HoldDownButton : System.Windows.Forms.Form
{
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.Button btnRewind;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.Button btnPlay;
private System.ComponentModel.IContainer components = null;

public HoldDownButton()
{
InitializeComponent();
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(this.thread != null && this.thread.IsAlive)
this.thread.Abort();

if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.btnRewind = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.btnPlay = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// progressBar1
//
this.progressBar1.Anchor =
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.progressBar1.Location = new System.Drawing.Point(0, 0);
this.progressBar1.Maximum = 200;
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(704, 24);
this.progressBar1.Step = 1;
this.progressBar1.TabIndex = 0;
//
// btnRewind
//
this.btnRewind.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnRewind.Location = new System.Drawing.Point(320, 152);
this.btnRewind.Name = "btnRewind";
this.btnRewind.TabIndex = 1;
this.btnRewind.Text = "Rewind";
this.btnRewind.MouseUp += new
System.Windows.Forms.MouseEventHandler(this.btnRewind_MouseUp);
this.btnRewind.MouseDown += new
System.Windows.Forms.MouseEventHandler(this.btnRewind_MouseDown);
//
// timer1
//
this.timer1.Interval = 150;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// btnPlay
//
this.btnPlay.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
this.btnPlay.Location = new System.Drawing.Point(224, 152);
this.btnPlay.Name = "btnPlay";
this.btnPlay.TabIndex = 2;
this.btnPlay.Text = "Play";
this.btnPlay.Click += new System.EventHandler(this.btnPlay_Click);
//
// HoldDownButton
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.BackColor = System.Drawing.SystemColors.Control;
this.ClientSize = new System.Drawing.Size(704, 254);
this.Controls.Add(this.btnPlay);
this.Controls.Add(this.btnRewind);
this.Controls.Add(this.progressBar1);
this.Name = "HoldDownButton";
this.Text = "Form1";
this.Load += new System.EventHandler(this.HoldDownButton_Load);
this.ResumeLayout(false);

}
#endregion

private Thread thread;

private void btnRewind_MouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
this.timer1.Start();
}

private void timer1_Tick(object sender, System.EventArgs e)
{
// this can only happen if the user didn't release the mouse before now.
begin continuous rewind
this.thread.Abort();
this.thread = new Thread(new ThreadStart(this.Rewind));
this.thread.Start();
this.timer1.Enabled = false; // prevent further timer events happening
}

private void HoldDownButton_Load(object sender, System.EventArgs e)
{
}

/// <summary>
/// Continuous rewind, mouse is held down beyond threshhold
/// </summary>
private void Rewind()
{
if(this.progressBar1.Value == 0)
return;
BeginInvoke(new UpdateProgressBarDelegate(this.UpdateProgressBar), new
object[]{-1});
Thread.Sleep(10);
Rewind();
}

/// <summary>
/// Just starts the progress bar running by itself
/// </summary>
private void Play()
{
BeginInvoke(new UpdateProgressBarDelegate(this.UpdateProgressBar), new
object[]{+1});
Thread.Sleep(25);
Play();
}

delegate void UpdateProgressBarDelegate(int change);
private void UpdateProgressBar(int change)
{
int newValue = this.progressBar1.Value + change;
if(newValue <= this.progressBar1.Maximum && newValue >=
this.progressBar1.Minimum)
this.progressBar1.Value = newValue; // increment
else
this.progressBar1.Value = 0; // reset to 0
}

private void btnPlay_Click(object sender, System.EventArgs e)
{
if(this.thread != null && this.thread.IsAlive)
{
this.thread.Abort();
this.thread.Join();
}
this.thread = new Thread(new ThreadStart(this.Play));
this.thread.Start();
}

private void btnRewind_MouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if(this.timer1.Enabled)
{
// mouse button released, rewind song
this.progressBar1.Value = 0;
this.timer1.Enabled = false;
}
else
{
// stop continuous rewind when user releases button
this.btnPlay.PerformClick();
}
}
}
}
 
hi,
just as a more direct reply to your question, i think the simplest solution
is to start a timer in the MouseDown, and then in the Tick event, you can
disable the timer. in MouseUp you can check if the timer is still running
and you'll know whether the hold-down was for longer than the timer or not.
i found this approach was simpler than using a StartTime and subtracting
DateTime.Now from it to see how long they have pressed the button, namely
because you actually want to invoke some code after the time has elapsed,
and the timer has this functionality built in.

hope this helps
tim
 
hi,
got your reply on my blog thanks.
multi-threading is something that will really make your application great.
i thought it sounded really complicated so for a long time i never used
those techniques in my applications, but i consider it a necessity now to
writing a good application. here is a good place to start (MSDN article)
with a nice simple example:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp

good luck
tim




Hi, I couldn't log back into developersdex.com. Thanks for the timing code.
I'm still pretty new to .net, I was told what it was about 4 months ago at
my new job. All the threading stuff you had is a bit advanced for me to
figure out, but the timer with the mouse up and down events I'm sure I'll
figure out how to implement. Thanks!
 
Back
Top