From: Alexis Laferrière Date: Wed, 20 Feb 2013 13:27:58 +0000 (-0500) Subject: examples: adds an example use of the gtk module, calculator X-Git-Tag: v0.6~48^2~7 X-Git-Url: http://nitlanguage.org examples: adds an example use of the gtk module, calculator Signed-off-by: Alexis Laferrière --- diff --git a/examples/calculator.nit b/examples/calculator.nit new file mode 100644 index 0000000..b658541 --- /dev/null +++ b/examples/calculator.nit @@ -0,0 +1,208 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Copyright 2013 Alexis Laferrière +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import gtk + +class CalculatorContext + var result : nullable Float = null + + var last_op : nullable Char = null + + var current : nullable Float = null + var after_point : nullable Int = null + + fun push_op( op : Char ) + do + apply_last_op_if_any + last_op = op # store for next push_op + + # prepare next current + after_point = null + current = null + end + + fun push_digit( digit : Int ) + do + var current = current + if current == null then current = 0.0 + + var after_point = after_point + if after_point == null then + current = current * 10.0 + digit.to_f + else + current = current + digit.to_f * 10.0.pow(after_point.to_f) + after_point -= 1 + end + + self.current = current + end + + fun switch_to_decimals + do + if after_point != null then return + + after_point = -1 + end + + fun apply_last_op_if_any + do + var op = last_op + + var result = result + if result == null then result = 0.0 + + var current = current + if current == null then current = 0.0 + + if op == null then + result = current + else if op == '+' then + result = result + current + else if op == '-' then + result = result - current + else if op == '/' then + result = result / current + else if op == '*' then + result = result * current + end + self.result = result + self.current = null + end +end + +class CalculatorGui + super GtkCallable + + var win : GtkWindow + var container : GtkGrid + + var lbl_disp : GtkLabel + var but_eq : GtkButton + + var context = new CalculatorContext + + redef fun signal( sender, user_data ) + do + if user_data isa Char then # is an operation + var c = user_data + if c == '.' then + context.switch_to_decimals + else + context.push_op( c ) + lbl_disp.text = context.result.to_s + end + else if user_data isa Int then # is a number + var n = user_data + context.push_digit( n ) + lbl_disp.text = context.current.to_s + end + end + + init + do + init_gtk + + win = new GtkWindow( 0 ) + + container = new GtkGrid(2,1,true) + win.add( container ) + + lbl_disp = new GtkLabel( "_" ) + container.attach( lbl_disp, 0, 0, 5, 1 ) + + # digits + for n in [0..9] do + var but = new GtkButton.with_label( n.to_s ) + but.set_size_request( 64, 64 ) + but.signal_connect( "clicked", self, n ) + if n == 0 then + container.attach( but, 0, 4, 1, 1 ) + else container.attach( but, (n-1)%3, 3-(n-1)/3, 1, 1 ) + end + + # operators + var r = 1 + for op in ['+', '-', '*', '/' ] do + var but = new GtkButton.with_label( op.to_s ) + but.set_size_request( 64, 64 ) + but.signal_connect( "clicked", self, op ) + container.attach( but, 4, r, 1, 1 ) + r+=1 + end + + # = + but_eq = new GtkButton.with_label( "=" ) + but_eq.set_size_request( 64, 64 ) + but_eq.signal_connect( "clicked", self, '=' ) + container.attach( but_eq, 5, 3, 1, 2 ) + + # . + var but_dot = new GtkButton.with_label( "." ) + but_dot.set_size_request( 64, 64 ) + but_dot.signal_connect( "clicked", self, '.' ) + container.attach( but_dot, 1, 4, 1, 1 ) + + win.show_all + end +end + +# context tests +var context = new CalculatorContext +context.push_digit( 1 ) +context.push_digit( 2 ) +context.push_op( '+' ) +context.push_digit( 3 ) +context.push_op( '*' ) +context.push_digit( 2 ) +context.push_op( '=' ) +var r = context.result.to_precision( 2 ) +assert r == "30.00" else print r + +context = new CalculatorContext +context.push_digit( 1 ) +context.push_digit( 4 ) +context.switch_to_decimals +context.push_digit( 1 ) +context.push_op( '*' ) +context.push_digit( 3 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "42.30" else print r + +context.push_op( '+' ) +context.push_digit( 1 ) +context.push_digit( 1 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "53.30" else print r + +context = new CalculatorContext +context.push_digit( 4 ) +context.push_digit( 2 ) +context.switch_to_decimals +context.push_digit( 3 ) +context.push_op( '/' ) +context.push_digit( 3 ) +context.push_op( '=' ) +r = context.result.to_precision( 2 ) +assert r == "14.10" else print r + +# graphical application + +if "NIT_TESTING".environ != "true" then + var app = new CalculatorGui + run_gtk +end diff --git a/tests/nitg-e.skip b/tests/nitg-e.skip index fbbfcd4..649d79e 100644 --- a/tests/nitg-e.skip +++ b/tests/nitg-e.skip @@ -6,6 +6,7 @@ test_extern test_ni_ test_ffi_ test_gtk +calculator nitc nitdoc nits diff --git a/tests/nitg-s.skip b/tests/nitg-s.skip index fbbfcd4..649d79e 100644 --- a/tests/nitg-s.skip +++ b/tests/nitg-s.skip @@ -6,6 +6,7 @@ test_extern test_ni_ test_ffi_ test_gtk +calculator nitc nitdoc nits diff --git a/tests/nitg.skip b/tests/nitg.skip index fbbfcd4..649d79e 100644 --- a/tests/nitg.skip +++ b/tests/nitg.skip @@ -6,6 +6,7 @@ test_extern test_ni_ test_ffi_ test_gtk +calculator nitc nitdoc nits diff --git a/tests/niti.skip b/tests/niti.skip index 7396ba9..cdc3c9a 100644 --- a/tests/niti.skip +++ b/tests/niti.skip @@ -7,6 +7,7 @@ test_ffi_ test_math test_mem test_gtk +calculator shoot_logic bench_ nit_args1 diff --git a/tests/sav/calculator.sav b/tests/sav/calculator.sav new file mode 100644 index 0000000..e69de29