Padre::Wx::StatusBar - Encapsulates status bar customizations


Padre documentation Contained in the Padre distribution.

Index


Code Index:

NAME

Top

Padre::Wx::StatusBar - Encapsulates status bar customizations

DESCRIPTION

Top

Padre::Wx::StatusBar implements Padre's status bar. It is the bottom pane holding various, err, status information on Padre.

The information shown are (in order):

* File name of current document, with a leading star if file has been updated and not saved
* (Optional) Icon showing status of background tasks
* (Optional) MIME type of current document
* Type of end of lines of current document
* Position in current document

It inherits from Wx::StatusBar, so check Wx documentation to see all the available methods that can be applied to it besides the added ones (see below).

METHODS

Top

new

    my $statusbar = Padre::Wx::StatusBar->new( $main );

Create and return a new Padre status bar. One should pass the $main Padre window as argument, to get a reference to the status bar parent.

clear

    $statusbar->clear;

Clear all the status bar fields, i.e. they will display an empty string in all fields.

say

    $statusbar->say('Hello World!');

Temporarily overwrite only the leftmost filename part of the status bar.

It will return to it's normal value when the status bar is next refreshed for normal reasons (such as a keystroke or a file panel switch).

refresh

    $statusbar->refresh;

Force an update of the document fields in the status bar.

update_task_status

    $statusbar->update_task_status;

Checks whether a task status icon update is in order and if so, changes the icon to one of the other states

update_pos

    $statusbar->update_pos;

Update the cursor position

on_resize

    $statusbar->on_resize( $event );

Handler for the EVT_SIZE $event. Used to move the task load bitmap to its position.

SEE ALSO

Top

Icons for background status courtesy of Mark James, at http://www.famfamfam.com/lab/icons/silk/.

COPYRIGHT & LICENSE

Top


Padre documentation Contained in the Padre distribution.
package Padre::Wx::StatusBar;

use 5.008;
use strict;
use warnings;
use Padre::Constant       ();
use Padre::Current        ();
use Padre::Util           ();
use Padre::Wx             ();
use Padre::Wx::Icon       ();
use Padre::Wx::Role::Main ();
use Padre::MimeTypes      ();

use Class::XSAccessor {
	accessors => {
		_task_sbmp   => '_task_sbmp',   # Static bitmap holding the task status
		_task_status => '_task_status', # Current task status
		_task_width  => '_task_width',  # Current width of task field
	}
};

our $VERSION = '0.86';
our @ISA     = qw{
	Padre::Wx::Role::Main
	Wx::StatusBar
};

use constant {
	FILENAME    => 0,
	TASKLOAD    => 1,
	HIGHLIGHTER => 2,
	MIMETYPE    => 3,
	NEWLINE     => 4,
	POSTRING    => 5,
	RDONLY      => 6,
};

#####################################################################

sub new {
	my $class = shift;
	my $main  = shift;

	# Create the basic object
	my $self = $class->SUPER::new(
		$main,
		-1,
		Wx::wxST_SIZEGRIP | Wx::wxFULL_REPAINT_ON_RESIZE
	);

	$self->{main} = $main;

	# create the static bitmap that will hold the task load status
	my $sbmp = Wx::StaticBitmap->new( $self, -1, Wx::wxNullBitmap );
	$self->_task_sbmp($sbmp);
	$self->_task_status('foobar'); # init status to sthg defined
	                               # Wx::Event::EVT_LEFT_DOWN(
	                               # $sbmp,
	                               # sub {
	                               # require Padre::TaskManager;
	                               # Padre::TaskManager::on_dump_running_tasks(@_);
	                               # },
	                               # );

	# Set up the fields
	$self->SetFieldsCount(7);

	#$self->SetStatusWidths( -1, 0, 100, 100, 50, 100 );

	# react to resize events, to adapt size of icon field
	Wx::Event::EVT_SIZE( $self, \&on_resize );

	return $self;
}

#####################################################################

sub clear {
	my $self = shift;
	$self->SetStatusText( "", FILENAME );
	$self->SetStatusText( "", HIGHLIGHTER );
	$self->SetStatusText( "", MIMETYPE );
	$self->SetStatusText( "", NEWLINE );
	$self->SetStatusText( "", POSTRING );
	$self->SetStatusText( "", RDONLY );
	return;
}

sub say {
	$_[0]->SetStatusText( $_[1], FILENAME );
}

sub refresh {
	my $self    = shift;
	my $current = $self->current;

	# Blank the status bar if no document is open
	my $editor = $current->editor or return $self->clear;

	# Prepare the various strings that form the status bar
	my $main     = $self->{main};
	my $notebook = $current->notebook;
	my $document = $current->document;
	my $newline  = $document->newline_type || Padre::Constant::NEWLINE;
	my $pageid   = $notebook->GetSelection;
	my $old      = $notebook->GetPageText($pageid);
	my $filename = $document->filename || '';
	my $text =
		$filename
		? File::Basename::basename($filename)
		: substr( $old, 1 );
	$self->{_last_editor}   = $editor;
	$self->{_last_modified} = $editor->GetModify;
	my $modified       = $self->{_last_modified} ? '*' : ' ';
	my $title          = $modified . $text;
	my $position       = $editor->GetCurrentPos;
	my $line           = $editor->GetCurrentLine;
	my $start          = $editor->PositionFromLine($line);
	my $lines          = $editor->GetLineCount;
	my $char           = $position - $start;
	my $width          = $self->GetCharWidth;
	my $highlighter    = Padre::MimeTypes->get_highlighter_name( $document->highlighter );
	my $mime_type_name = Padre::MimeTypes->get_mime_type_name( $document->mimetype );
	my $percent        = int( 100 * $line / $lines );

	# Set some defaults to advoid "use of uninittialized value" - messages:
	$mime_type_name = '???' if !defined($mime_type_name);

	#my $postring  = Wx::gettext('L:') . ( $line + 1  ) . ' ' . Wx::gettext('Ch:') . "$char $percent%";
	my $format   = '%' . length( $lines + 1 ) . 's,%-3s %3s%%';
	my $length   = length( $lines + 1 ) + 8;
	my $postring = sprintf( $format, ( $line + 1 ), $char, $percent );
	my $rdstatus = $self->is_read_only;

	# update task load status
	$self->update_task_status;

	# Write the new values into the status bar and update sizes
	if (    defined( $main->{infomessage} )
		and ( $main->{infomessage} ne '' )
		and ( $main->{infomessage_timeout} > time ) )
	{
		$self->SetStatusText( $main->{infomessage}, FILENAME );
	} else {
		my $config = $self->config;
		$self->{_template_} = $main->process_template( $config->main_statusbar_template );
		my $status = $main->process_template_frequent( $self->{_template_} );
		$self->SetStatusText( $status, FILENAME );
	}
	$self->SetStatusText( $highlighter,    HIGHLIGHTER );
	$self->SetStatusText( $mime_type_name, MIMETYPE );
	$self->SetStatusText( $newline,        NEWLINE );
	$self->SetStatusText( $postring,       POSTRING );
	$self->SetStatusText( $rdstatus,       RDONLY );
	$self->SetStatusWidths(
		-1,
		$self->_task_width,
		( length($highlighter) + 2 ) * $width,
		( length($mime_type_name) + 2 ) * $width,
		( length($newline) + 2 ) * $width,
		( $length + 2 ) * $width,
		( length($rdstatus) + 2 ) * $width,
	);

	# Move the static bitmap holding the task load status
	$self->_move_bitmap;

	# Fixed ticket #190: Massive GDI object leakages
	# http://padre.perlide.org/ticket/190
	# Please remember to call SetPageText once per the same text
	# This still leaks but far less slowly (just on undo)
	if ( $old ne $title ) {
		$notebook->SetPageText( $pageid, $title );
	}

	return;
}

sub update_task_status {
	my $self   = shift;
	my $status = $self->_get_task_status;
	return if $status eq $self->_task_status; # Nothing to do

	# Store new status
	$self->_task_status($status);
	my $sbmp = $self->_task_sbmp;

	# If we're idling, just hide the icon in the statusbar
	if ( $status eq 'idle' ) {
		$sbmp->Hide;
		$sbmp->SetBitmap(Wx::wxNullBitmap);
		$sbmp->SetToolTip('');
		$self->_task_width(0);
		return;
	}

	# Not idling, show the correct icon in the statusbar
	$sbmp->SetBitmap( Padre::Wx::Icon::find("status/padre-tasks-$status") );
	$sbmp->SetToolTip(
		$status eq 'running'
		? Wx::gettext('Background Tasks are running')
		: Wx::gettext('Background Tasks are running with high load')
	);
	$sbmp->Show;
	$self->_task_width(20);
}

sub update_pos {
	my $self = shift;

	my $current  = $self->current;
	my $editor   = $current->editor or return $self->clear;
	my $position = $editor->GetCurrentPos;

	# Skip expensive update if there is nothing to update:
	return if defined( $self->{Last_Pos} ) and ( $self->{Last_Pos} == $position );

	# Detect modification:
	unless (defined( $self->{_last_editor} )
		and ( $self->{_last_editor} eq $editor )
		and defined( $self->{_last_modified} )
		and ( $self->{_last_modified} == $editor->GetModify ) )
	{

		# Either the tab has changed or the file has been modified:
		$self->refresh;

	}

	$self->{Last_Pos} = $position;

	my $line    = $editor->GetCurrentLine;
	my $start   = $editor->PositionFromLine($line);
	my $lines   = $editor->GetLineCount;
	my $char    = $position - $start;
	my $percent = int( 100 * $line / $lines );

	my $format = '%' . length( $lines + 1 ) . 's,%-3s %3s%%';
	my $postring = sprintf( $format, ( $line + 1 ), $char, $percent );

	$self->SetStatusText( $postring, POSTRING );


}

# this sub is called frequently, on every key stroke or mouse movement
# TODO speed should be improved
sub refresh_from_template {
	my $self = shift;

	return unless $self->{_template_};

	my $main   = $self->{main};
	my $status = $main->process_template_frequent( $self->{_template_} );
	$self->SetStatusText( $status, FILENAME );

	return;
}

#####################################################################

sub on_resize {
	my ($self) = @_;

	# note: parent resize method will be called automatically

	$self->_move_bitmap;
	$self->Refresh;
}

#####################################################################
# Private methods

#
# my $status = $self->_get_task_status;
#
# return 'idle', 'running' or 'load' depending on the number of threads
# currently working.
#
sub _get_task_status {
	my $self    = shift;
	my $manager = undef; # $self->current->ide->task_manager;

	# still in editor start-up phase, default to idle
	return 'idle' unless defined $manager;

	my $running = $manager->running_tasks;
	return 'idle' unless $running;

	my $max_workers = $manager->max_no_workers;
	my $jobs        = $manager->task_queue->pending + $running;

	# high load is defined as the state when the number of
	# running and pending jobs is larger that twice the
	# MAXIMUM number of workers
	return ( $jobs > 2 * $max_workers ) ? 'load' : 'running';
}

#
# $statusbar->_move_bitmap;
#
# move the static bitmap holding the task load status to its proper location.
#
sub _move_bitmap {
	my ($self) = @_;
	my $sbmp   = $self->_task_sbmp;
	my $rect   = $self->GetFieldRect(TASKLOAD);
	my $size   = $sbmp->GetSize;
	$sbmp->Move(
		$rect->GetLeft + ( $rect->GetWidth - $size->GetWidth ) / 2,
		$rect->GetTop +  ( $rect->GetHeight - $size->GetHeight ) / 2,
	);
	$sbmp->Refresh;
}

sub is_read_only {
	my ($self) = @_;

	my $document = $self->current->document;
	return '' unless defined($document);

	return $document->is_readonly ? Wx::gettext('Read Only') : Wx::gettext('R/W');
}


1;

# Copyright 2008-2011 The Padre development team as listed in Padre.pm.
# LICENSE
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl 5 itself.