[gtkmm] ScrolledWindow doesn't scroll a DrawingArea
- From: "Nik A. Melchior" <nik alum wustl edu>
- To: gtkmm-list gnome org
- Subject: [gtkmm] ScrolledWindow doesn't scroll a DrawingArea
- Date: Wed, 23 Jul 2003 14:00:06 -0500
I can't seem to find a sufficiently complicated example of
ScrolledWindow to help me with this problem. I'm trying to create a
ScrolledWindow that is initially centered on a DrawingArea of unknown
size (i.e. may be larger or smaller than the ScrolledWindow). However,
the scrollbars won't allow me to scroll, despite the fact that the
accessors for the associated Adjustments seem to indicate that their
entire range is not currently visible within one page size.
If I set the ScrolledWindow policy to POLICY_AUTOMATIC, the scrollbars
do not appear, despite the fact that the entire Pixbuf is clearly not
visible at once.
I'm new to GUI design, so most of this code is borrowed from examples
and mailing lists. In fact, I found a gtk+ example that does precisely
what I want, and converted it to gtkmm, but the scrollbars still fail.
Thank you in advance for your consideration.
--
Nik A. Melchior Washington University
GPG Key Fingerprint (see http://www.gnupg.org/):
F824 BB7F 5424 04D0 0EBF 2AE7 7BB9 533C 380A 0462
//FIXME: copyright notice
// $Id$
#ifndef LOCALIZE_VIEWER_H
#define LOCALIZE_VIEWER_H
#define UPDATE_DELAY 50
#include <gtkmm.h>
class LocalizeViewer : public Gtk::Window {
public:
LocalizeViewer (void);
virtual ~LocalizeViewer (void);
private:
// Load the map file and create an image of the map,
// and set map_buf_{width,height}.
// Returns true if it succeeds.
bool create_map_pixbuf (void);
void adjust_scrollbars (void);
// signal handlers
void on_close_clicked (void);
bool on_drawing_area_expose (GdkEventExpose *event);
bool on_timeout (void);
Gtk::HBox top_hbox;
Gtk::ScrolledWindow scroll_pane;
Gtk::DrawingArea drawing_area;
Glib::RefPtr<Gdk::Pixbuf> pixbuf_ref, map_pixbuf_ref;
guint map_buf_width, map_buf_height;
SigC::Connection timeout_connection;
Gtk::Alignment close_button_aligned;
Gtk::Button close_button;
};
#endif //header guard
//FIXME: copyright notice
// $Id$
#include <gdkmm.h>
#include <iostream>
#include "localize_viewer.h"
LocalizeViewer::LocalizeViewer (void) :
map_buf_width(0),
map_buf_height(0),
close_button_aligned(Gtk::ALIGN_CENTER, Gtk::ALIGN_BOTTOM, 0.0, 0.0),
close_button(Gtk::Stock::QUIT)
{
set_title("SMRT LocalizeViewer");
set_border_width(10);
//FIXME: check returns of following 2 lines
create_map_pixbuf();
pixbuf_ref = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB,
FALSE, // has_alpha
8, // bits/pixel
map_buf_width, map_buf_height);
// policy can also be POLICY_AUTOMATIC; first horizontal, then vertical
scroll_pane.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
scroll_pane.set_border_width(10);
scroll_pane.set_size_request(200, 200);
// register callbacks
drawing_area.signal_expose_event().connect(
slot(*this, &LocalizeViewer::on_drawing_area_expose));
timeout_connection = Glib::signal_timeout().connect(
slot(*this, &LocalizeViewer::on_timeout), UPDATE_DELAY);
close_button.signal_clicked().connect(
slot(*this, &LocalizeViewer::on_close_clicked));
// place all the widgets
scroll_pane.add(drawing_area); // creates viewport for me
adjust_scrollbars();
top_hbox.pack_start(scroll_pane);
close_button_aligned.add(close_button);
top_hbox.pack_end(close_button_aligned);
add(top_hbox);
show_all_children();
set_size_request(300, 300);
}
LocalizeViewer::~LocalizeViewer (void)
{
// should probably happen anyway
timeout_connection.disconnect();
}
bool
LocalizeViewer::create_map_pixbuf (void)
{
if (map_pixbuf_ref)
map_pixbuf_ref->unreference();
map_pixbuf_ref = Gdk::Pixbuf::create_from_file("background.jpg");
/* FIXME: eventually, something like this:
* create_from_data((guint8 *)map_rgb_data,
* Gdk::COLORSPACE_RGB,
* FALSE, // has_alpha
* 8, // bits per pixel
* map_width,
* map_height,
* rowstride, // distance in bytes b/w rows
* destroy_slot); // used to free data when
* // pixbuf's refcount drops to 0
*/
map_buf_width = map_pixbuf_ref->get_width();
map_buf_height = map_pixbuf_ref->get_height();
std::cout << "map_buf size: (" << map_buf_width << ", " << map_buf_height
<< ")." << std::endl;
return true;
}
void
LocalizeViewer::on_close_clicked (void)
{
hide();
}
bool
LocalizeViewer::on_drawing_area_expose (GdkEventExpose *event)
{
gint rowstride = pixbuf_ref->get_rowstride();
const guchar * pixels = pixbuf_ref->get_pixels()
+ (rowstride * event->area.y) + (event->area.x * 3);
Glib::RefPtr<Gdk::Window> window_ref = drawing_area.get_window();
Glib::RefPtr<Gdk::GC> gc_ref = drawing_area.get_style()->get_black_gc();
window_ref->draw_rgb_image(gc_ref,
0, 0,
map_buf_width, map_buf_height,
Gdk::RGB_DITHER_NORMAL,
pixels,
rowstride);
return true;
}
void
LocalizeViewer::adjust_scrollbars (void)
{
Gtk::Adjustment *h_adj = scroll_pane.get_hadjustment();
Gtk::Adjustment *v_adj = scroll_pane.get_vadjustment();
int start_x = (int) (((float)scroll_pane.get_width() - map_buf_width)
/ -2.0);
int start_y = (int) (((float)scroll_pane.get_height() - map_buf_height)
/ -2.0);
h_adj->set_lower(MIN(start_x, 0));
h_adj->set_upper(MAX(map_buf_width, map_buf_width - start_x));
h_adj->set_page_size(scroll_pane.get_width());
h_adj->changed();
h_adj->set_value((h_adj->get_upper() - h_adj->get_lower()
- scroll_pane.get_width()) / 2 + h_adj->get_lower());
h_adj->value_changed();
v_adj->set_lower(MIN(start_y, 0));
v_adj->set_upper(MAX(map_buf_height, map_buf_height - start_y));
v_adj->set_page_size(scroll_pane.get_height());
v_adj->changed();
v_adj->set_value((v_adj->get_upper() - v_adj->get_lower()
- scroll_pane.get_height()) / 2 + v_adj->get_lower());
v_adj->value_changed();
std::cout << "Start pos: (" << start_x << ", " << start_y << "). ";
std::cout << "Scrollbar pos: (" << h_adj->get_value() << ", "
<< v_adj->get_value() << ") of (" << h_adj->get_lower()
<< ", " << v_adj->get_lower() << ") to ("
<< h_adj->get_upper() << ", " << v_adj->get_upper()
<< ")." << std::endl;
}
bool
LocalizeViewer::on_timeout()
{
// This copies an unaltered version of the map
// into the pixbuf_ref, which is the one actually displayed.
map_pixbuf_ref->copy_area(0, 0, map_buf_width, map_buf_height,
pixbuf_ref, 0, 0);
drawing_area.queue_draw();
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]