Re: Two SimpleLists with one data stucture
- From: muppet <scott asofyet org>
- To: Vasya Leushin <basileus newmail ru>
- Cc: gtk-perl mailing list <gtk-perl-list gnome org>
- Subject: Re: Two SimpleLists with one data stucture
- Date: Fri, 2 Jun 2006 12:53:39 -0400
On May 30, 2006, at 11:51 AM, Vasya Leushin wrote:
muppet ÐÐÑÐÑ:
Some questions come up that prevent me coming up with a useful
example... what should the combo renderer display when not
showing the
menu, what do the columns mean, etc, etc. Can you describe the
context
of the problem in a bit more detail?
Columns 1 is a number of channel, col 2 is a name of the channel, they
are not editable.
Col 3 is a value of corresponding channel (editable) which we can
change by editing the cell.
Model for col 4 contains array of presets, where each element is
array
with 2 numbers (max. value and mid. value)
and one string as a description (3 elements in total). CellRenderer
(which is combo)for this model
should display only descriptions and nothing else. If i choose one of
these descriptions in the combo
then two things happen:
1. This description appears in the cell
2. Corresponding mid. value goes to column 3.
In case of 'Blue' this is 15. So, we can forget max value for a
while...
This sort of interaction starts to get a little painful in
SimpleList, so here's a simplistic stab at that functionality with
the bare TreeView API. This displays your data in three view
columns, the Number, Name, and Value columns. The value column is
editable, allowing the user to type a number, but also has a pulldown
menu of presets. The tricky bit here is that the CellRendererCombo
will fill the entry with the text of the menu item, which is a
string, not a number, so we have to look up the corresponding value
when the cell is edited. Also, from what i can tell, you cannot
control the display of the menu beyond telling it to display one
particular column. To change that behavior you'd have to either
subclass the CellRendererCombo and override the START_EDITING method
in order to customize the menu, etc, or write a new custom cell
renderer. (There are cell renderer examples in the Gtk2 source
distribution.)
Other tricks here involve using named constants for the column
indices (because i kept forgetting what was what), view columns
unrelated to model columns, using a nontrivial cell-edited callback
which mangles the input data, and storing the CellRendererCombo's
model in a column of the main model.
-=-=-=-=-=-=-
#!/usr/bin/perl -w
use strict;
use Glib ':constants';
use Gtk2 -init;
# Column types for the main model
use constant {
CHANNEL_NUMBER => 0,
CHANNEL_NAME => 1,
CHANNEL_VALUE => 2,
CHANNEL_PRESETS => 3, # list of presets for this channel
};
my @main_column_types;
$main_column_types[CHANNEL_NUMBER] = 'Glib::Int';
$main_column_types[CHANNEL_NAME] = 'Glib::String';
$main_column_types[CHANNEL_VALUE] = 'Glib::Int';
$main_column_types[CHANNEL_PRESETS] = 'Gtk2::ListStore';
# Column types for the subvalue models
use constant {
PRESET_MAXVAL => 0,
PRESET_MIDVAL => 1,
PRESET_NAME => 2,
};
my @preset_column_types;
$preset_column_types[PRESET_MAXVAL] = 'Glib::Int';
$preset_column_types[PRESET_MIDVAL] = 'Glib::Int';
$preset_column_types[PRESET_NAME] = 'Glib::String';
#
# now create a model and fill it.
#
my $model = Gtk2::ListStore->new (@main_column_types);
foreach (
[1, 'Volume', 0, [[255, 32, 'Preset1'], [255, 192, 'Preset2']]],
[2, 'Pan', 64, [[128, 0, 'Hard left'], [128, 128, 'Hard
right']]],
[3, 'Treble', 128, [[255, 196, 'high frequencies']]],
[4, 'Mid', 128, [[255, 64, 'midrange frequencies']]],
[5, 'Bass', 128, [[255, 140, 'low frequencies']]],
) {
my ($number, $name, $value, $presets) = @$_;
my $submodel = Gtk2::ListStore->new (@preset_column_types);
foreach my $p (@$presets) {
$submodel->set ($submodel->append,
PRESET_MAXVAL, $p->[0],
PRESET_MIDVAL, $p->[1],
PRESET_NAME, $p->[2]);
}
$model->set ($model->append,
CHANNEL_NUMBER, $number,
CHANNEL_NAME, $name,
CHANNEL_VALUE, $value,
CHANNEL_PRESETS, $submodel);
}
#
# now set up a view for that model
#
my $treeview = Gtk2::TreeView->new ($model);
# The first two columns are rather boring.
$treeview->insert_column_with_attributes
(-1, 'Number', Gtk2::CellRendererText->new, text => CHANNEL_NUMBER);
$treeview->insert_column_with_attributes
(-1, 'Name', Gtk2::CellRendererText->new, text => CHANNEL_NAME);
# For displaying and editing the value, we'll use the CellRendererCombo.
# This will display the current value, and offer an entry to edit it;
# but when in editing mode, there will also be a little button that
allows
# the user to pull down a menu of presets.
my $cell = Gtk2::CellRendererCombo->new;
$cell->set (editable => TRUE, # without this, it's just a text cell
text_column => PRESET_NAME); # submodel col to display in the menu
$treeview->insert_column_with_attributes (-1, "Value", $cell,
text => CHANNEL_VALUE,
model => CHANNEL_PRESETS);
$cell->signal_connect (edited => sub {
my ($cell, $path_string, $new_text) = @_;
my $iter = $model->get_iter (Gtk2::TreePath->new_from_string
($path_string));
# If the user chose a preset, we will receive the text of the preset
# name, since that's what was shown in the menu. We can't set that
# into the value column, so we'll have to look up the corresponding
# value from the submodel.
if ($new_text !~ /^\d+$/) {
my $submodel = $model->get ($iter, CHANNEL_PRESETS);
my $subiter = $submodel->get_iter_first;
while ($subiter) {
my $name = $submodel->get ($subiter, PRESET_NAME);
$new_text = $submodel->get ($subiter, PRESET_MIDVAL)
if $new_text eq $name;
$subiter = $submodel->iter_next ($subiter);
}
}
# note that if the user typed text that wasn't a preset name, this
# could still not be a number.
$model->set ($iter, CHANNEL_VALUE, $new_text)
if $new_text =~ /^\d+$/;
});
#
# and, finally, put all of that on the screen.
#
my $window = Gtk2::Window->new;
$window->signal_connect (destroy => sub { Gtk2->main_quit });
$window->add ($treeview);
$window->set_default_size (300, 0);
$window->show_all;
Gtk2->main;
--
I bring the rock, and provided it is fiscally responsible, I will
bring the funk as well. And that's fo-shizzle.
-- Saturday Night Live
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]