Skip to content

Commit

Permalink
Adding backspace, styling font
Browse files Browse the repository at this point in the history
Equation font now styled using Pango, to American Typewriter typeface.
Need to figure out how to right align, since Alignment on the Layout
doesn't seem to work.  Also need to set fallback typefaces.
Implementing dot button click.  Catching ParserException on
ParseFormula.  Added backspace button, supposed to use GTK 'undo' icon,
instead just shows 'Undo' text.  Need to fix 'Clear' button to show an
icon, too.  Adding Eric White credit to README.
  • Loading branch information
cheshire137 committed Apr 15, 2012
1 parent fd38a7c commit 26ac998
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 54 deletions.
13 changes: 10 additions & 3 deletions Calculator/Equation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ namespace Calculator
public class Equation
{
private readonly string _equation;
public const char EXECUTE_OPERATOR = '=';
public const char CLEAR_OPERATOR = 'C';
public static List<char> Operators = new List<char> { '/', '+', '-', '*' };
public static List<char> Operators = new List<char> { '/', '+', '-',
'*', '.' };

public Equation(string equation)
{
Expand All @@ -19,6 +18,10 @@ public Equation(string equation)

public bool HasFinalOperator()
{
if (string.IsNullOrEmpty(_equation))
{
return false;
}
bool result = false;
foreach (char op in Operators) {
if (_equation.EndsWith(op.ToString())) {
Expand All @@ -31,6 +34,10 @@ public bool HasFinalOperator()

public string ReplaceFinalOperator(char newOp)
{
if (string.IsNullOrEmpty(_equation))
{
return newOp.ToString();
}
return _equation.TrimEnd(Operators.ToArray()) + newOp;
}

Expand Down
87 changes: 66 additions & 21 deletions Main/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
public partial class MainWindow : Gtk.Window
{
private const string ERROR_MESSAGE = "ERROR";
private const string FONT_DESCRIPTION = "American Typewriter Regular 24";
private Pango.Layout _equationLayout = null;
private string _equationText = "0";

public MainWindow() : base (Gtk.WindowType.Toplevel)
{
Expand Down Expand Up @@ -84,7 +87,16 @@ protected void OnButton0Clicked(object sender, System.EventArgs e)

protected void OnButtonDotClicked(object sender, System.EventArgs e)
{
throw new System.NotImplementedException();
if (ERROR_MESSAGE.Equals(_equationText))
{
changeEquationText("0.");
return;
}
var eq = new Equation(_equationText);
if (!eq.HasFinalOperator())
{
changeEquationText(_equationText + ".");
}
}

protected void OnButtonAddClicked(object sender, System.EventArgs e)
Expand All @@ -94,55 +106,88 @@ protected void OnButtonAddClicked(object sender, System.EventArgs e)

protected void OnButtonEqualsClicked(object sender, System.EventArgs e)
{
Formula formula = SimpleFormulaParser.ParseFormula(
equationTextView.Buffer.Text
);
//Console.WriteLine(sym.Inspect());
try
{
equationTextView.Buffer.Text = "" + formula.Solve();
Formula formula = SimpleFormulaParser.ParseFormula(
_equationText
);
changeEquationText("" + formula.Solve());
}
catch (ParserException ex)
{
equationTextView.Buffer.Text = ERROR_MESSAGE;
changeEquationText(ERROR_MESSAGE);
Console.WriteLine(ex.Message);
}
catch (DivideByZeroException ex)
catch (DivideByZeroException)
{
equationTextView.Buffer.Text = ERROR_MESSAGE;
changeEquationText(ERROR_MESSAGE);
}
}

protected void OnButtonClearClicked(object sender, System.EventArgs e)
{
equationTextView.Buffer.Text = "0";
changeEquationText("0");
}

private void operatorButtonClicked(char op)
{
if (ERROR_MESSAGE.Equals(equationTextView.Buffer.Text))
if (ERROR_MESSAGE.Equals(_equationText))
{
equationTextView.Buffer.Text = "0" + op;
changeEquationText("0" + op);
return;
}
var eq = new Equation(equationTextView.Buffer.Text);
var eq = new Equation(_equationText);
if (eq.HasFinalOperator()) {
equationTextView.Buffer.Text = eq.ReplaceFinalOperator(op);
changeEquationText(eq.ReplaceFinalOperator(op));
}
else
{
equationTextView.Buffer.Text += op;
changeEquationText(_equationText + op);
}
}

private void numberButtonClicked(int number)
{
string curEquation = equationTextView.Buffer.Text;
if ("0".Equals(curEquation) ||
ERROR_MESSAGE.Equals(curEquation)) {
equationTextView.Buffer.Text = "" + number;
if ("0".Equals(_equationText) ||
ERROR_MESSAGE.Equals(_equationText)) {
changeEquationText("" + number);
return;
}
equationTextView.Buffer.Text += number;
}
changeEquationText(_equationText + number);
}

protected void OnEquationAreaExposeEvent(object o, Gtk.ExposeEventArgs args)
{
changeEquationText(_equationText);
}

private void changeEquationText(string value)
{
if (null == _equationLayout)
{
_equationLayout = new Pango.Layout(this.PangoContext);
_equationLayout.Wrap = Pango.WrapMode.Word;
_equationLayout.Alignment = Pango.Alignment.Right;
_equationLayout.FontDescription =
Pango.FontDescription.FromString(FONT_DESCRIPTION);
}
_equationText = value;
_equationLayout.SetMarkup(_equationText);
equationArea.GdkWindow.Clear();
equationArea.GdkWindow.DrawLayout(
equationArea.Style.TextGC(StateType.Normal), 5, 5, _equationLayout
);
}

protected void OnButtonBackspaceClicked(object sender, System.EventArgs e)
{
string valueAfterBackspace = _equationText.Remove(
_equationText.Length - 1
);
if (string.IsNullOrEmpty(valueAfterBackspace))
{
valueAfterBackspace = "0";
}
changeEquationText(valueAfterBackspace);
}
}
38 changes: 22 additions & 16 deletions Main/gtk-gui/MainWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ public partial class MainWindow
private global::Gtk.VBox equationVbox;
private global::Gtk.HBox equationClearHbox;
private global::Gtk.Button buttonClear;
private global::Gtk.ScrolledWindow GtkScrolledWindow;
private global::Gtk.TextView equationTextView;
private global::Gtk.Button buttonBackspace;
private global::Gtk.DrawingArea equationArea;
private global::Gtk.VBox vbox2;
private global::Gtk.HBox hbox1;
private global::Gtk.Button button7;
Expand Down Expand Up @@ -50,6 +50,7 @@ protected virtual void Build ()
this.equationClearHbox.Spacing = 6;
// Container child equationClearHbox.Gtk.Box+BoxChild
this.buttonClear = new global::Gtk.Button ();
this.buttonClear.HeightRequest = 50;
this.buttonClear.CanFocus = true;
this.buttonClear.Name = "buttonClear";
this.buttonClear.UseStock = true;
Expand All @@ -61,20 +62,23 @@ protected virtual void Build ()
w1.Expand = false;
w1.Fill = false;
// Container child equationClearHbox.Gtk.Box+BoxChild
this.GtkScrolledWindow = new global::Gtk.ScrolledWindow ();
this.GtkScrolledWindow.Name = "GtkScrolledWindow";
this.GtkScrolledWindow.ShadowType = ((global::Gtk.ShadowType)(1));
// Container child GtkScrolledWindow.Gtk.Container+ContainerChild
this.equationTextView = new global::Gtk.TextView ();
this.equationTextView.Buffer.Text = "0";
this.equationTextView.Name = "equationTextView";
this.equationTextView.Editable = false;
this.equationTextView.CursorVisible = false;
this.equationTextView.Justification = ((global::Gtk.Justification)(1));
this.GtkScrolledWindow.Add (this.equationTextView);
this.equationClearHbox.Add (this.GtkScrolledWindow);
global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.equationClearHbox [this.GtkScrolledWindow]));
w3.Position = 1;
this.buttonBackspace = new global::Gtk.Button ();
this.buttonBackspace.CanFocus = true;
this.buttonBackspace.Name = "buttonBackspace";
this.buttonBackspace.UseStock = true;
this.buttonBackspace.UseUnderline = true;
this.buttonBackspace.Label = "gtk-undo";
this.equationClearHbox.Add (this.buttonBackspace);
global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.equationClearHbox [this.buttonBackspace]));
w2.Position = 1;
w2.Expand = false;
w2.Fill = false;
// Container child equationClearHbox.Gtk.Box+BoxChild
this.equationArea = new global::Gtk.DrawingArea ();
this.equationArea.Name = "equationArea";
this.equationClearHbox.Add (this.equationArea);
global::Gtk.Box.BoxChild w3 = ((global::Gtk.Box.BoxChild)(this.equationClearHbox [this.equationArea]));
w3.Position = 2;
this.equationVbox.Add (this.equationClearHbox);
global::Gtk.Box.BoxChild w4 = ((global::Gtk.Box.BoxChild)(this.equationVbox [this.equationClearHbox]));
w4.Position = 0;
Expand Down Expand Up @@ -317,6 +321,8 @@ protected virtual void Build ()
this.Show ();
this.DeleteEvent += new global::Gtk.DeleteEventHandler (this.OnDeleteEvent);
this.buttonClear.Clicked += new global::System.EventHandler (this.OnButtonClearClicked);
this.buttonBackspace.Clicked += new global::System.EventHandler (this.OnButtonBackspaceClicked);
this.equationArea.ExposeEvent += new global::Gtk.ExposeEventHandler (this.OnEquationAreaExposeEvent);
this.button7.Clicked += new global::System.EventHandler (this.OnButton7Clicked);
this.button8.Clicked += new global::System.EventHandler (this.OnButton8Clicked);
this.button9.Clicked += new global::System.EventHandler (this.OnButton9Clicked);
Expand Down
34 changes: 21 additions & 13 deletions Main/gtk-gui/gui.stetic
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<child>
<widget class="Gtk.Button" id="buttonClear">
<property name="MemberName" />
<property name="HeightRequest">50</property>
<property name="CanFocus">True</property>
<property name="UseStock">True</property>
<property name="Type">StockItem</property>
Expand All @@ -41,23 +42,30 @@
</packing>
</child>
<child>
<widget class="Gtk.ScrolledWindow" id="GtkScrolledWindow">
<widget class="Gtk.Button" id="buttonBackspace">
<property name="MemberName" />
<property name="ShadowType">In</property>
<child>
<widget class="Gtk.TextView" id="equationTextView">
<property name="MemberName" />
<property name="ShowScrollbars">True</property>
<property name="Editable">False</property>
<property name="CursorVisible">False</property>
<property name="Text" translatable="yes">0</property>
<property name="Justification">Right</property>
</widget>
</child>
<property name="CanFocus">True</property>
<property name="UseStock">True</property>
<property name="Type">StockItem</property>
<property name="StockId">gtk-undo</property>
<signal name="Clicked" handler="OnButtonBackspaceClicked" />
<property name="label">gtk-undo</property>
</widget>
<packing>
<property name="Position">1</property>
<property name="AutoSize">False</property>
<property name="AutoSize">True</property>
<property name="Expand">False</property>
<property name="Fill">False</property>
</packing>
</child>
<child>
<widget class="Gtk.DrawingArea" id="equationArea">
<property name="MemberName" />
<signal name="ExposeEvent" handler="OnEquationAreaExposeEvent" />
</widget>
<packing>
<property name="Position">2</property>
<property name="AutoSize">True</property>
</packing>
</child>
</widget>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Snazzy Calculator

This is intended to be a simple calculator written using GTK#, for the purpose of experimenting with GTK# and MonoDevelop. I release all its source code under the [GPL v3 license](http://www.gnu.org/licenses/gpl.html).
This is intended to be a simple calculator written using GTK#, for the purpose of experimenting with GTK# and MonoDevelop. I release all its source code under the [GPL v3 license](http://www.gnu.org/licenses/gpl.html). Many thanks to Eric White for his [tutorial on building a recursive descent parser in C#](http://ericwhite.com/blog/map/recursive-descent-parser/).
38 changes: 38 additions & 0 deletions SnazzyCalculator.sln
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AE0669A5-A066-42FE-A505-236CE726D667}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
LICENSE.txt = LICENSE.txt
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Util", "Util\Util.csproj", "{2EA3D357-B917-4808-90BC-13AD85AFB54A}"
Expand Down Expand Up @@ -43,6 +44,43 @@ Global
$2.FileWidth = 120
$2.inheritsSet = VisualStudio
$2.inheritsScope = text/plain
$0.TextStylePolicy = $3
$3.inheritsSet = null
$3.scope = text/x-csharp
$0.CSharpFormattingPolicy = $4
$4.IndentSwitchBody = True
$4.AnonymousMethodBraceStyle = NextLine
$4.PropertyBraceStyle = NextLine
$4.PropertyGetBraceStyle = NextLine
$4.PropertySetBraceStyle = NextLine
$4.EventBraceStyle = NextLine
$4.EventAddBraceStyle = NextLine
$4.EventRemoveBraceStyle = NextLine
$4.StatementBraceStyle = NextLine
$4.IfElseBraceForcement = AddBraces
$4.ForBraceForcement = AddBraces
$4.WhileBraceForcement = AddBraces
$4.UsingBraceForcement = AddBraces
$4.FixedBraceForcement = AddBraces
$4.BeforeMethodDeclarationParentheses = False
$4.BeforeMethodCallParentheses = False
$4.BeforeConstructorDeclarationParentheses = False
$4.BeforeIndexerDeclarationBracket = False
$4.BeforeDelegateDeclarationParentheses = False
$4.NewParentheses = False
$4.SpacesBeforeBrackets = False
$4.inheritsSet = Mono
$4.inheritsScope = text/x-csharp
$4.scope = text/x-csharp
$0.TextStylePolicy = $5
$5.NoTabsAfterNonTabs = True
$5.RemoveTrailingWhitespace = True
$5.inheritsSet = VisualStudio
$5.inheritsScope = text/plain
$5.scope = text/plain
$0.StandardHeader = $6
$6.Text = @ \n ${FileName}\n \n Author:\n ${AuthorName} <${AuthorEmail}>\n\n Copyright (c) ${Year} ${CopyrightHolder}\n\n This program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\n You should have received a copy of the GNU General Public License\n along with this program. If not, see <http://www.gnu.org/licenses/>.
$6.IncludeInNewFiles = True
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 26ac998

Please sign in to comment.