dynamically resize text in the big clock, first version

git-svn-id: svn://localhost/ardour2/branches/3.0@6494 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-01-15 14:42:19 +00:00
parent 81fd8dd960
commit 11edfd035e
6 changed files with 192 additions and 15 deletions

View File

@ -197,6 +197,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
engine = 0;
_session_is_new = false;
big_clock_window = 0;
big_clock_height = 0;
big_clock_resize_in_progress = false;
session_selector_window = 0;
last_key_press_time = 0;
_will_create_new_session_automatically = false;

View File

@ -313,6 +313,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
AudioClock big_clock;
Gtk::Window* big_clock_window;
void big_clock_size_allocate (Gtk::Allocation&);
bool idle_big_clock_text_resizer (int width, int height);
void big_clock_realized ();
bool big_clock_resize_in_progress;
int big_clock_height;
void float_big_clock (Gtk::Window* parent);
bool main_window_state_event_handler (GdkEventWindowState*, bool window_was_editor);

View File

@ -536,13 +536,22 @@ ARDOUR_UI::setup_clock ()
big_clock_window->set_title (_("Big Clock"));
big_clock_window->set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY);
big_clock_window->signal_realize().connect (sigc::bind (sigc::ptr_fun (set_decoration), big_clock_window, (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH)));
big_clock_window->signal_realize().connect (sigc::mem_fun (*this, &ARDOUR_UI::big_clock_realized));
big_clock_window->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBigClock")));
big_clock_window->signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), big_clock_window), false);
big_clock_window->signal_size_allocate().connect (sigc::mem_fun (*this, &ARDOUR_UI::big_clock_size_allocate));
manage_window (*big_clock_window);
}
void
ARDOUR_UI::big_clock_realized ()
{
set_decoration (big_clock_window, (Gdk::DECOR_BORDER|Gdk::DECOR_RESIZEH));
int x, y, w, d;
big_clock_window->get_window()->get_geometry (x, y, w, big_clock_height, d);
}
void
ARDOUR_UI::float_big_clock (Gtk::Window* parent)
{
@ -555,3 +564,111 @@ ARDOUR_UI::float_big_clock (Gtk::Window* parent)
}
}
void
ARDOUR_UI::big_clock_size_allocate (Gtk::Allocation& allocation)
{
if (!big_clock_resize_in_progress) {
Glib::signal_idle().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::idle_big_clock_text_resizer), 0, 0));
big_clock_resize_in_progress = true;
}
big_clock_window->set_size_request (allocation.get_width() - 2, allocation.get_height() - 1);
}
bool
ARDOUR_UI::idle_big_clock_text_resizer (int win_w, int win_h)
{
extern void get_pixel_size (Glib::RefPtr<Pango::Layout> layout, int& width, int& height);
Glib::RefPtr<Gdk::Window> win = big_clock_window->get_window();
assert (win);
big_clock_resize_in_progress = false;
Pango::FontDescription fd (big_clock.get_style()->get_font());
string family = fd.get_family();
int size = fd.get_size ();
int original_size;
bool absolute = fd.get_size_is_absolute ();
int stepsize;
if (!absolute) {
size /= PANGO_SCALE;
}
original_size = size;
int x, y, winw, winh, d;
int w, h;
int slop;
int limit;
win->get_geometry (x, y, winw, winh, d);
Glib::RefPtr<Pango::Layout> layout = big_clock.create_pango_layout ("0");
get_pixel_size (layout, w, h);
/* we want about 10% of the font height as padding, and we'll allow 10% of slop
in the accuracy of the fit.
*/
slop = 10;
limit = winh - (h/4);
if (h < limit && limit - h < slop) {
/* current font is smaller than the window height but not by too much */
return false;
}
stepsize = 16;
if (h > limit) {
/* font is too big, lets get smaller */
size -= stepsize;
} else {
/* font is too big, lets get bigger */
size += stepsize;
}
while (1) {
char buf[family.length()+16];
snprintf (buf, family.length()+16, "%s %d", family.c_str(), size);
Pango::FontDescription fd (buf);
layout->set_font_description (fd);
get_pixel_size (layout, w, h);
if (abs (h - limit) < slop) {
if (size != original_size) {
/* use the size from the last loop */
Glib::RefPtr<Gtk::RcStyle> rcstyle = big_clock.get_modifier_style ();
rcstyle->set_font (fd);
big_clock.modify_style (rcstyle);
}
break;
}
if (h > limit) {
/* too big, stepsize should be smaller */
if (size < 2) {
break;
}
size -= stepsize;
} else if (h < limit) {
/* too small (but not small enough): step size should be bigger */
if (size > 720) {
break;
}
size += stepsize;
}
stepsize /= 2;
}
return false;
}

View File

@ -2044,30 +2044,30 @@ AudioClock::set_mode (Mode m)
void
AudioClock::set_size_requests ()
{
/* note that in some fonts, "88" is narrower than "00", hence the 2 pixel padding */
/* note that in some fonts, "88" is narrower than "00" */
switch (_mode) {
case Timecode:
Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (hours_label, "-88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (minutes_label, "88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (seconds_label, "88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (frames_label, "88", 5, 5);
break;
case BBT:
Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-000", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "0000", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (bars_label, "-888", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (beats_label, "88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ticks_label, "8888", 5, 5);
break;
case MinSec:
Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "00", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "00.000", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ms_hours_label, "88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ms_minutes_label, "88", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (ms_seconds_label, "88.888", 5, 5);
break;
case Frames:
Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "0000000000", 5, 5);
Gtkmm2ext::set_size_request_to_display_given_text (audio_frames_label, "8888888888", 5, 5);
break;
case Off:
@ -2082,3 +2082,47 @@ AudioClock::set_bbt_reference (nframes64_t pos)
{
bbt_reference_time = pos;
}
void
AudioClock::on_style_changed (const Glib::RefPtr<Style>& old_style)
{
HBox::on_style_changed (old_style);
/* propagate style changes to all component widgets that should inherit the main one */
Glib::RefPtr<RcStyle> rcstyle = get_modifier_style();
clock_base.modify_style (rcstyle);
audio_frames_label.modify_style (rcstyle);
hours_label.modify_style (rcstyle);
minutes_label.modify_style (rcstyle);
seconds_label.modify_style (rcstyle);
frames_label.modify_style (rcstyle);
bars_label.modify_style (rcstyle);
beats_label.modify_style (rcstyle);
ticks_label.modify_style (rcstyle);
ms_hours_label.modify_style (rcstyle);
ms_minutes_label.modify_style (rcstyle);
ms_seconds_label.modify_style (rcstyle);
hours_ebox.modify_style (rcstyle);
minutes_ebox.modify_style (rcstyle);
seconds_ebox.modify_style (rcstyle);
frames_ebox.modify_style (rcstyle);
audio_frames_ebox.modify_style (rcstyle);
bars_ebox.modify_style (rcstyle);
beats_ebox.modify_style (rcstyle);
ticks_ebox.modify_style (rcstyle);
ms_hours_ebox.modify_style (rcstyle);
ms_minutes_ebox.modify_style (rcstyle);
ms_seconds_ebox.modify_style (rcstyle);
colon1.modify_style (rcstyle);
colon2.modify_style (rcstyle);
colon3.modify_style (rcstyle);
colon4.modify_style (rcstyle);
colon5.modify_style (rcstyle);
b1.modify_style (rcstyle);
b2.modify_style (rcstyle);
set_size_requests ();
}

View File

@ -216,6 +216,7 @@ class AudioClock : public Gtk::HBox, public ARDOUR::SessionHandlePtr
static const uint32_t field_length[(int)AudioFrames+1];
static bool _has_focus;
void on_style_changed (const Glib::RefPtr<Gtk::Style>&);
};
#endif /* __audio_clock_h__ */

View File

@ -45,6 +45,14 @@ Gtkmm2ext::get_ink_pixel_size (Glib::RefPtr<Pango::Layout> layout,
height = (ink_rect.get_height() + PANGO_SCALE / 2) / PANGO_SCALE;
}
void
get_pixel_size (Glib::RefPtr<Pango::Layout> layout,
int& width,
int& height)
{
layout->get_pixel_size (width, height);
}
void
Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *text,
gint hpadding, gint vpadding)
@ -53,7 +61,7 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w, const gchar *
int width, height;
w.ensure_style ();
get_ink_pixel_size (w.create_pango_layout (text), width, height);
get_pixel_size (w.create_pango_layout (text), width, height);
w.set_size_request(width + hpadding, height + vpadding);
}
@ -69,7 +77,7 @@ Gtkmm2ext::set_size_request_to_display_given_text (Gtk::Widget &w,
w.ensure_style ();
for (vector<string>::const_iterator i = strings.begin(); i != strings.end(); ++i) {
get_ink_pixel_size (w.create_pango_layout (*i), width, height);
get_pixel_size (w.create_pango_layout (*i), width, height);
width_max = max(width_max,width);
height_max = max(height_max, height);
}