using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace FlipFlop
{
/// <summary>
/// Form1 の概要の説明です。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components = null;
public Form1()
{
//
// Windows フォーム デザイナ サポートに必要です。
//
InitializeComponent();
//
// TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
//
}
/// <summary>
/// 使用されているリソースに後処理を実行します。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
private void InitializeComponent()
{
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
this.ClientSize = new System.Drawing.Size(432, 310);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
}
#endregion
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
// 最大分割数
private const int divisionMax = 50;
// RS-FF
private RSFlipFlop rsff;
// 値の状態推移
private Queue transitionQ;
private Queue transitionInput1;
private Queue transitionInput2;
// 波形出力用ピクチャボックス
private PictureBox pictureBoxSignal;
// 波形出力用タイマー
private Timer timerSignal;
// 入力信号用チェックボックス
private CheckBox checkBoxInput1;
private CheckBox checkBoxInput2;
// フォーム読込時
private void Form1_Load(object sender, System.EventArgs e)
{
// フリップフロップ
rsff = new RSFlipFlop();
// 値の状態推移
transitionQ = new Queue( divisionMax );
for ( int i = 0; i < divisionMax; i++ )
{
transitionQ.Enqueue( rsff.Q );
}
transitionInput1 = new Queue( divisionMax );
for ( int i = 0; i < divisionMax; i++ )
{
transitionInput1.Enqueue( rsff.S );
}
transitionInput2 = new Queue( divisionMax );
for ( int i = 0; i < divisionMax; i++ )
{
transitionInput2.Enqueue( rsff.R );
}
// フォーム
this.ClientSize = new Size( 340, 250 );
this.Text = "FlipFlop";
this.FormBorderStyle = FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
// pictureBoxSignal
pictureBoxSignal = new PictureBox();
pictureBoxSignal.Location = new Point( 10, 10 );
pictureBoxSignal.Size = new Size( 320, 200 );
pictureBoxSignal.Paint += new PaintEventHandler( this.pictureBoxSignal_Paint );
this.Controls.Add( pictureBoxSignal );
// timerSignal
timerSignal = new Timer();
timerSignal.Interval = 200;
timerSignal.Tick += new EventHandler( this.timerSignal_Tick );
timerSignal.Start();
// checkBoxInput
checkBoxInput1 = new CheckBox();
checkBoxInput1.Text = "入力1";
checkBoxInput1.Checked = false;
checkBoxInput1.Location = new Point( 50, 220 );
checkBoxInput1.Size = new Size( 100, 20 );
checkBoxInput1.CheckedChanged += new EventHandler( this.checkBoxInput_CheckedChanged );
checkBoxInput2 = new CheckBox();
checkBoxInput2.Text = "入力2";
checkBoxInput2.Checked = false;
checkBoxInput2.Location = new Point( 170, 220 );
checkBoxInput2.Size = new Size( 100, 20 );
checkBoxInput2.CheckedChanged += new EventHandler( this.checkBoxInput_CheckedChanged );
this.Controls.Add( checkBoxInput1 );
this.Controls.Add( checkBoxInput2 );
}
// チェックボックスのチェック状態が変化したとき
private void checkBoxInput_CheckedChanged( object sender, EventArgs e )
{
// 各チェックボックスのチェック状態を信号のありなしと解釈
ExBoolean S = checkBoxInput1.Checked;
ExBoolean R = checkBoxInput2.Checked;
rsff.Set( S, R );
}
// 描画処理呼び出し
private void pictureBoxSignal_Paint( object sender, PaintEventArgs e )
{
RefreshSignal( e.Graphics );
}
// 波形出力用タイマー
private void timerSignal_Tick( object sender, EventArgs e )
{
// 状態推移を更新
transitionQ.Dequeue();
transitionQ.Enqueue( rsff.Q );
transitionInput1.Dequeue();
transitionInput1.Enqueue( rsff.S );
transitionInput2.Dequeue();
transitionInput2.Enqueue( rsff.R );
// 信号波形を描画
Graphics g = pictureBoxSignal.CreateGraphics();
RefreshSignal( g );
g.Dispose();
}
// 信号波形を描画する
private void RefreshSignal( Graphics g )
{
if ( g == null ) return;
// バッファを作成
Bitmap bBuff = new Bitmap( pictureBoxSignal.Width, pictureBoxSignal.Height );
Graphics gBuff = Graphics.FromImage( (Image)bBuff );
// 黒で背景をクリア
gBuff.Clear( Color.Black );
float waveWidth = pictureBoxSignal.Width / (float)divisionMax;
float x = pictureBoxSignal.Width;
float y = 20.0f;
ExBoolean valLast = new ExBoolean( false );
// Qの波形を出力
gBuff.DrawString( "Signal of Q", Control.DefaultFont, Brushes.LightGreen, 0, y + 35.0f );
foreach ( ExBoolean val in transitionQ )
{
if ( val.IsTrue() )
{
if ( valLast.IsFalse() ) gBuff.DrawLine( Pens.LightGreen, x, y + 30.0f, x, y );
gBuff.DrawLine( Pens.LightGreen, x, y, x - waveWidth, y);
}
else
{
if ( valLast.IsTrue() ) gBuff.DrawLine( Pens.LightGreen, x, y + 30.0f, x, y );
gBuff.DrawLine( Pens.LightGreen, x, y + 30.0f, x - waveWidth, y + 30.0f );
}
x -= waveWidth;
valLast = val;
}
// 入力1の波形を出力
x = pictureBoxSignal.Width;
y = 100.0f;
valLast = new ExBoolean( false );
gBuff.DrawString( "Signal of input 1", Control.DefaultFont, Brushes.Orange, 0, y + 25.0f );
foreach ( ExBoolean val in transitionInput1 )
{
if ( val.IsTrue() )
{
if ( valLast.IsFalse() ) gBuff.DrawLine( Pens.Orange, x, y + 20.0f, x, y );
gBuff.DrawLine( Pens.Orange, x, y, x - waveWidth, y);
}
else
{
if ( valLast.IsTrue() ) gBuff.DrawLine( Pens.Orange, x, y + 20.0f, x, y );
gBuff.DrawLine( Pens.Orange, x, y + 20.0f, x - waveWidth, y + 20.0f );
}
x -= waveWidth;
valLast = val;
}
// 入力2の波形を出力
x = pictureBoxSignal.Width;
y = 140.0f;
valLast = new ExBoolean( false );
gBuff.DrawString( "Signal of input 2", Control.DefaultFont, Brushes.Yellow, 0, y + 25.0f );
foreach ( ExBoolean val in transitionInput2 )
{
if ( val.IsTrue() )
{
if ( valLast.IsFalse() ) gBuff.DrawLine( Pens.Yellow, x, y + 20.0f, x, y );
gBuff.DrawLine( Pens.Yellow, x, y, x - waveWidth, y);
}
else
{
if ( valLast.IsTrue() ) gBuff.DrawLine( Pens.Yellow, x, y + 20.0f, x, y );
gBuff.DrawLine( Pens.Yellow, x, y + 20.0f, x - waveWidth, y + 20.0f );
}
x -= waveWidth;
valLast = val;
}
// バッファをコピー
g.DrawImage( bBuff, 0, 0 );
// バッファをディスポーズ
gBuff.Dispose();
bBuff.Dispose();
}
}
}