App-InvestSim

 view release on metacpan or  search on metacpan

lib/App/InvestSim/GUI.pm  view on Meta::CPAN

                                       -state => 'readonly', -justify => 'right', -takefocus => 0,
                                       -style => 'DataTable.TEntry');
        $e->g_grid(-column => $i + 1, -row => $j + 1, -sticky => "we");
        $e->g_bind('<FocusIn>', sub { set_core_table_selected_state($e);
                                      update_displayed_table($i, $j) });
      }
    }
  }

  # Build the right bar with some other input values and the output values not 
  # depending on the loan parameters.
  {
    my $frame = $root->new_ttk__frame(-padding => 3);
    $frame->g_grid(-column => 2, -row => 0, -rowspan => 3, -sticky => "we");
    
    my $row = 0;
    
    for my $c (['rent_delay', "Delai de mise en location", \&format_year],
               ['loan_delay', "Durée de franchise de l'emprunt", \&format_year],
               ['application_fees', "Frais de dossier du prêt", \&format_euro],
               ['mortgage_fees', "Frais d'hypothèque", \&format_percent],
               ['social_tax', "CSG + CRDS + Solidarité", \&format_percent]) {
      add_input_entry($frame, \$row, @$c);
    }
    
    # Just some empty white-space between the inputs and the output fields.
    $frame->g_grid_rowconfigure($row++, -minsize => 10);
    
    $frame->new_ttk__label(-text => "Revenus total du loyer (net) :")
      ->g_grid(-column => 0, -row => $row, -sticky => "e", -padx => "0 2");
    $frame->new_ttk__entry(-width => ENTRY_WIDTH, -state => 'readonly', -textvariable => \$total_rent_text, -takefocus => 0)
      ->g_grid(-column => 1, -row => $row++, -sticky => "we", -pady => 2);

    $frame->new_ttk__label(-text => "Plafond du loyer :")
      ->g_grid(-column => 0, -row => $row, -sticky => "e", -padx => "0 2");
    ($rent_cap_entry = $frame->new_ttk__entry(-width => ENTRY_WIDTH, -state => 'readonly', -textvariable => \$rent_cap_text, -takefocus => 0))
      ->g_grid(-column => 1, -row => $row++, -sticky => "we", -pady => 2);

      $frame->new_ttk__label(-text => "Valeur déductible du bien :")
      ->g_grid(-column => 0, -row => $row, -sticky => "e", -padx => "0 2");
    $frame->new_ttk__entry(-width => ENTRY_WIDTH, -state => 'readonly', -textvariable => \$pinel_worth_text, -takefocus => 0)
      ->g_grid(-column => 1, -row => $row++, -sticky => "we", -pady => 2);

    $frame->new_ttk__label(-text => "Frais de notaire :")
      ->g_grid(-column => 0, -row => $row, -sticky => "e", -padx => "0 2");
    $frame->new_ttk__entry(-width => ENTRY_WIDTH, -state => 'readonly', -textvariable => \$notary_fees_text, -takefocus => 0)
      ->g_grid(-column => 1, -row => $row++, -sticky => "we", -pady => 2);

      $frame->new_ttk__label(-text => "Montant total investi :")
      ->g_grid(-column => 0, -row => $row, -sticky => "e", -padx => "0 2");
    $frame->new_ttk__entry(-width => ENTRY_WIDTH, -state => 'readonly', -textvariable => \$total_invested_text, -takefocus => 0)
      ->g_grid(-column => 1, -row => $row++, -sticky => "we", -pady => 2);
  }

  # Build the bottom table.
  $root->g_grid_columnconfigure(1, -weight => 1);
  $root->g_grid_rowconfigure(3, -weight => 1);
  {
    my $frame = $root->new_ttk__frame(-padding => 3, -height => 550);
    $frame->g_grid_propagate(0);
    $frame->g_grid(-column => 0, -row => 3, -columnspan => 3, -sticky => "nwes");
    $frame->g_grid_columnconfigure(0, -weight => 1);
    $frame->g_grid_rowconfigure(0, -weight => 1);
    $display_table = $frame->new_ttk__treeview(-height => ($values{duration} // 20) + 2);
    $display_table->g_grid(-column => 0, -row => 0, -rowspan => 2, -sticky => "nwes");
    
    # We're setting a specific font for items with the tag 'total'.
    $display_table->m_tag('configure', 'total', -font => $treeview_total_font);
    
    #my $hscroll = $frame->new_tk__scrollbar(-orient => "horizontal", -command => [$display_table, "xview"]);
    #$hscroll->g_grid(-column => 0, -row => 1, -sticky => "we");
    my $vscroll = $frame->new_ttk__scrollbar(-orient => "vertical", -command => [$display_table, "yview"]);
    $vscroll->g_grid(-column => 1, -row => 0, -sticky => "ns");
    $frame->new_ttk__sizegrip()->g_grid(-column => 1, -row => 1, -sticky => "se");
    $display_table->configure(-yscrollcommand => [$vscroll, "set"]);
    #$display_table->configure(-xscrollcommand => [$hscroll, "set"]);
    
    my @headings = ('Année', 'Loyer net', 'Placements', 'Principal du prêt', 'Intérêts du prêt', 'Frais du prêt', 'Revenus imposable', 'Déficit déductible', 'Impôt', 'Solde annuel', 'Capital');
    # We're not using the name of the columns (c1, c2, ...) we're only using their
    # index (#0, #1, ...), including #0 the index of the first implicit column.
    $display_table->m_configure(-columns => [map { "c$_" } 1..$#headings ]);
    for my $c (0..$#headings) {
      my $width = Tkx::font_measure(Tkx::ttk__style_lookup('Heading', '-font'), $headings[$c]);
      $display_table->m_heading("#${c}", -text => $headings[$c]);
      $display_table->m_column("#${c}", -width => $width, -anchor => 'e');
    }
  }

  # Finally, we create a small menu.
  {
    my $menu = $root->new_menu;
    $root->configure(-menu => $menu);
    my $file = $menu->new_menu;
    $menu->m_add_cascade(-menu => $file, -label => "Fichier", -underline => 0);
    $file->m_add_command(-label => "Nouveau", -accelerator => 'Ctrl+N', -underline => 0,
                         -command => sub { init_values(); refresh_all_fields() });
    $root->g_bind('<Control-n>', sub { init_values(); refresh_all_fields() });
    $file->m_add_command(-label => "Ouvrir...", -accelerator => 'Ctrl+O', -underline => 0,
                         -command => sub { open_values(); refresh_all_fields() });
    $root->g_bind('<Control-o>', sub { open_values(); refresh_all_fields() });
    $file->m_add_command(-label => "Enregistrer", -accelerator => 'Ctrl+S', -underline => 0, -command => \&save_values);
    $root->g_bind('<Control-s>', \&save_values);
    $file->m_add_command(-label => "Enregistrer sous...", -accelerator => 'Ctrl+Alt+S',  -underline => 12,-command => \&save_values_as);
    $root->g_bind('<Control-Alt-s>', \&save_values_as);
    $file->add_separator();
    $file->m_add_command(-label => "Quitter", -accelerator => 'Alt+F4',  -underline => 0,-command => sub { $root->g_destroy() });
    # The binding for Alt-F4 is automatically supplied by Windows and can't be
    # overriden. It will destroy the window. We catch it as well as the menu entry
    # using the following bind command.
    # If we bind to $root, then the event triggers for all contained widget.
    $root->g_bind('<Destroy>', [sub { autosave() if $_[0] eq '.' }, Tkx::Ev('%W')]);

    my $options = $menu->new_menu;
    $menu->m_add_cascade(-menu => $options, -label => "Options", -underline => 0);
    my $automatic_duration = \$values{automatic_duration};
    $options->m_add_checkbutton(-label => "Durée automatique", -variable => $automatic_duration, -onvalue => 1, -offvalue => 0, -accelerator => 'Ctrl+D');
    $root->g_bind('<Control-d>', sub { $$automatic_duration = 1 - $$automatic_duration });

    my $taxes = $menu->new_menu;
    $menu->m_add_cascade(-menu => $taxes, -label => "Fiscalité", -underline => 1);
    my $pinel_menu = $taxes->new_menu;



( run in 0.976 second using v1.01-cache-2.11-cpan-2398b32b56e )