summaryrefslogtreecommitdiffstats
path: root/beos/PicWindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'beos/PicWindow.cpp')
-rw-r--r--beos/PicWindow.cpp369
1 files changed, 369 insertions, 0 deletions
diff --git a/beos/PicWindow.cpp b/beos/PicWindow.cpp
new file mode 100644
index 000000000..6b30f27c2
--- /dev/null
+++ b/beos/PicWindow.cpp
@@ -0,0 +1,369 @@
+#include <app/Application.h>
+#include <interface/Bitmap.h>
+#include <interface/Box.h>
+#include <interface/Button.h>
+#include <interface/CheckBox.h>
+#include <interface/RadioButton.h>
+#include <interface/Screen.h>
+#include <interface/StringView.h>
+
+#include "PicWindow.h"
+#include "Stepper.h"
+
+#define MSG_PREV 'prev'
+#define MSG_NEXT 'next'
+#define MSG_CLOSE 'clos'
+#define MSG_WIDTH 'widt'
+#define MSG_HEIGHT 'heig'
+#define MSG_RADIO 'radi'
+
+PicView::PicView( hb_handle_t * handle, int index )
+ : BView( BRect( 0,0,10,10 ), NULL, B_FOLLOW_NONE, B_WILL_DRAW )
+{
+ fHandle = handle;
+
+ /* Get the title and the job */
+ hb_list_t * list;
+ list = hb_get_titles( fHandle );
+ fTitle = (hb_title_t *) hb_list_item( list, index );
+ fJob = fTitle->job;
+
+ /* We'll start with the first picture */
+ fIndex = 0;
+
+ /* Allocate a buffer large enough to call hb_get_preview() later */
+ fRawPic = (uint8_t *) malloc( ( fTitle->width + 2 ) *
+ ( fTitle->height + 2 ) * 4 );
+
+ /* Create the RGB BBitmap we'll use to display */
+ fBitmap = new BBitmap( BRect( 0, 0, fTitle->width + 1,
+ fTitle->height + 1 ), 0, B_RGB32 );
+
+ /* Now build the interface */
+ BRect r, b;
+ BBox * box;
+ BButton * button;
+ BStringView * stringView;
+
+ /* Resize ourselves so the picture fits just fine */
+ b = fBitmap->Bounds();
+ ResizeTo( b.Width()+170, b.Height()+65 );
+
+ /* Now build the UI around the BBitmap */
+ SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
+
+ /* "Size" box */
+ b = Bounds();
+ r = BRect( b.right-150,10,b.right-10,105 );
+ box = new BBox( r );
+ box->SetLabel( "Size" );
+ AddChild( box );
+
+ b = box->Bounds();
+
+ /* Width */
+ r = BRect( 10,15,b.right/2,35 );
+ stringView = new BStringView( r, NULL, "Width:" );
+ box->AddChild( stringView );
+ r = BRect( b.right/2+1,15,b.right-10,35 );
+ fWidthStepper = new HBStepper( r, 16, 16, fTitle->width,
+ fJob->width, new BMessage( MSG_WIDTH ) );
+ box->AddChild( fWidthStepper );
+
+ /* Height */
+ r = BRect( 10,40,b.right/2,60 );
+ stringView = new BStringView( r, NULL, "Height:" );
+ box->AddChild( stringView );
+ r = BRect( b.right/2+1,40,b.right-10,60 );
+ fHeightStepper = new HBStepper( r, 16, 16, fTitle->height,
+ fJob->height, new BMessage( MSG_HEIGHT ) );
+ box->AddChild( fHeightStepper );
+
+ /* Aspect ratio */
+ r = BRect( 10,65,b.right-10,85 );
+ fRatioCheck = new BCheckBox( r, NULL, "Keep aspect ratio",
+ new BMessage( MSG_WIDTH ) );
+ fRatioCheck->SetValue( fJob->keep_ratio );
+ box->AddChild( fRatioCheck );
+
+ /* "Crop" box */
+ b = Bounds();
+ r = BRect( b.right-150,115,b.right-10,260 );
+ box = new BBox( r );
+ box->SetLabel( "Crop" );
+ AddChild( box );
+
+ b = box->Bounds();
+
+ /* Automatic */
+ r = BRect( 10,15,b.right-10,35 );
+ fAutoRadio = new BRadioButton( r, NULL, "Automatic",
+ new BMessage( MSG_RADIO ) );
+ box->AddChild( fAutoRadio );
+
+ /* Custom */
+ r = BRect( 10,40,b.right-10,60 );
+ fCustomRadio = new BRadioButton( r, NULL, "Custom:",
+ new BMessage( MSG_RADIO ) );
+ box->AddChild( fCustomRadio );
+ float width = ( b.Width() - 30 ) / 2;
+ r = BRect( (b.right-width)/2,65,(b.right+width)/2,85 );
+ fCropSteppers[0] = new HBStepper( r, 2, 0, fTitle->height/2-2,
+ fJob->crop[0], new BMessage( MSG_WIDTH ) );
+ box->AddChild( fCropSteppers[0] );
+ r = BRect( (b.right-width)/2,115,(b.right+width)/2,135 );
+ fCropSteppers[1] = new HBStepper( r, 2, 0, fTitle->height/2-2,
+ fJob->crop[1], new BMessage( MSG_WIDTH ) );
+ box->AddChild( fCropSteppers[1] );
+ r = BRect( 10,90,10+width,110 );
+ fCropSteppers[2] = new HBStepper( r, 2, 0, fTitle->width/2-2,
+ fJob->crop[2], new BMessage( MSG_HEIGHT ) );
+ box->AddChild( fCropSteppers[2] );
+ r = BRect( width+20,90,b.right-10,110 );
+ fCropSteppers[3] = new HBStepper( r, 2, 0, fTitle->width/2-2,
+ fJob->crop[3], new BMessage( MSG_HEIGHT ) );
+ box->AddChild( fCropSteppers[3] );
+
+ if( memcmp( fTitle->crop, fJob->crop, 4 * sizeof( int ) ) )
+ {
+ fCustomRadio->SetValue( 1 );
+ }
+ else
+ {
+ fAutoRadio->SetValue( 1 );
+ }
+
+ /* "Misc" box */
+ b = Bounds();
+ r = BRect( b.right-150,270,b.right-10,315 );
+ box = new BBox( r );
+ box->SetLabel( "Misc" );
+ AddChild( box );
+
+ b = box->Bounds();
+
+ /* Deinterlace */
+ r = BRect( 10,15,b.right-10,35 );
+ fDeintCheck = new BCheckBox( r, NULL, "Deinterlace picture",
+ new BMessage( MSG_WIDTH ) );
+ fDeintCheck->SetValue( fJob->deinterlace );
+ box->AddChild( fDeintCheck );
+
+ b = Bounds();
+
+ /* Next/Prev buttons */
+ r = BRect( b.right-90,325,b.right-10,350 );
+ fPrevButton = new BButton( r, NULL, "Previous",
+ new BMessage( MSG_PREV ) );
+ AddChild( fPrevButton );
+ r = BRect( b.right-90,355,b.right-10,380 );
+ fNextButton = new BButton( r, NULL, "Next",
+ new BMessage( MSG_NEXT ) );
+ AddChild( fNextButton );
+
+ /* Info string and OK button */
+ r = BRect( 10,b.bottom-30,b.right-100,b.bottom-10 );
+ fInfoString = new BStringView( r, NULL, "" );
+ AddChild( fInfoString );
+ r = BRect( b.right-90,b.bottom-35,b.right-10,b.bottom-10 );
+ button = new BButton( r, NULL, "OK", new BMessage( MSG_CLOSE ) );
+ AddChild( button );
+
+ /* Process and draw a first picture */
+ RadioChanged();
+ UpdateBitmap();
+}
+
+PicView::~PicView()
+{
+ free( fRawPic );
+ delete fBitmap;
+}
+
+/************************************************************************
+ * PicView::Draw
+ ************************************************************************
+ * Calls the inherited BView::Draw, plus draws the BBitmap preview
+ * and the horizontal line above the info string and OK button
+ ***********************************************************************/
+void PicView::Draw( BRect rect )
+{
+ BRect b;
+
+ BView::Draw( rect );
+
+ if( LockLooper() )
+ {
+ b = fBitmap->Bounds();
+ DrawBitmap( fBitmap, BRect( 10,10,b.Width()+10,b.Height()+10 ) );
+ UnlockLooper();
+ }
+
+ b = Bounds();
+ SetHighColor( 128,128,128 );
+ StrokeLine( BPoint( 10,b.bottom-45 ), BPoint( b.right-10,b.bottom-45 ) );
+ SetHighColor( 255,255,255 );
+ StrokeLine( BPoint( 10,b.bottom-44 ), BPoint( b.right-10,b.bottom-44 ) );
+}
+
+void PicView::HandleMessage( BMessage * msg )
+{
+ switch( msg->what )
+ {
+ case MSG_PREV:
+ fIndex--;
+ UpdateBitmap();
+ break;
+
+ case MSG_NEXT:
+ fIndex++;
+ UpdateBitmap();
+ break;
+
+ case MSG_WIDTH:
+ case MSG_HEIGHT:
+ UpdateSettings( msg->what );
+ UpdateBitmap();
+ break;
+
+ case MSG_RADIO:
+ RadioChanged();
+ break;
+
+ }
+}
+
+void PicView::RadioChanged()
+{
+ int cus = fCustomRadio->Value();
+ for( int i = 0; i < 4; i++ )
+ {
+ fCropSteppers[i]->SetEnabled( cus );
+ }
+ if( !cus )
+ {
+ memcpy( fJob->crop, fTitle->crop, 4 * sizeof( int ) );
+ for( int i = 0; i < 4; i++ )
+ {
+ fCropSteppers[i]->SetValue( fJob->crop[i] );
+ }
+ UpdateSettings( MSG_WIDTH );
+ UpdateBitmap();
+ }
+}
+
+void PicView::UpdateSettings( uint32 what )
+{
+ fJob->width = fWidthStepper->Value();
+ fJob->height = fHeightStepper->Value();
+ fJob->keep_ratio = fRatioCheck->Value();
+ fJob->deinterlace = fDeintCheck->Value();
+ for( int i = 0; i < 4; i++ )
+ {
+ fJob->crop[i] = fCropSteppers[i]->Value();
+ }
+
+ if( fJob->keep_ratio )
+ {
+ if( what == MSG_WIDTH )
+ {
+ hb_fix_aspect( fJob, HB_KEEP_WIDTH );
+ if( fJob->height > fTitle->height )
+ {
+ fJob->height = fTitle->height;
+ hb_fix_aspect( fJob, HB_KEEP_HEIGHT );
+ }
+ }
+ else
+ {
+ hb_fix_aspect( fJob, HB_KEEP_HEIGHT );
+ if( fJob->width > fTitle->width )
+ {
+ fJob->width = fTitle->width;
+ hb_fix_aspect( fJob, HB_KEEP_WIDTH );
+ }
+ }
+ }
+
+ fWidthStepper->SetValue( fJob->width );
+ fHeightStepper->SetValue( fJob->height );
+}
+
+void PicView::UpdateBitmap()
+{
+ /* Sanity checks */
+ if( fIndex < 0 )
+ {
+ fIndex = 0;
+ return;
+ }
+ if( fIndex > 9 )
+ {
+ fIndex = 9;
+ return;
+ }
+
+ /* Enable/disable buttons */
+ fPrevButton->SetEnabled( fIndex > 0 );
+ fNextButton->SetEnabled( fIndex < 9 );
+
+ /* Get new preview and copy it in our BBitmap */
+ hb_get_preview( fHandle, fTitle, fIndex, fRawPic );
+ for( int i = 0; i < fTitle->height + 2; i++ )
+ {
+ memcpy( ( (uint8_t *) fBitmap->Bits() ) +
+ i * fBitmap->BytesPerRow(),
+ fRawPic + 4 * ( fTitle->width + 2 ) * i,
+ 4 * ( fTitle->width + 2 ) );
+ }
+
+ /* Update size info */
+ char text[1024];
+ snprintf( text, 1024, "Source: %dx%d, output: %dx%d",
+ fTitle->width, fTitle->height,
+ fJob->width, fJob->height );
+ fInfoString->SetText( text );
+
+ /* Force redraw */
+ Draw( Bounds() );
+}
+
+PicWindow::PicWindow( hb_handle_t * handle, int index )
+ : BWindow( BRect( 0,0,10,10 ), "Picture settings",
+ B_FLOATING_WINDOW_LOOK, B_MODAL_APP_WINDOW_FEEL,
+ B_NOT_CLOSABLE | B_NOT_RESIZABLE | B_NOT_ZOOMABLE )
+{
+ /* Add the PicView */
+ fView = new PicView( handle, index );
+ AddChild( fView );
+
+ /* Resize to fit */
+ ResizeTo( fView->Bounds().Width(), fView->Bounds().Height() );
+
+ /* Center */
+ BScreen screen;
+ MoveTo( ( screen.Frame().Width() - fView->Bounds().Width() ) / 2,
+ ( screen.Frame().Height() - fView->Bounds().Height() ) / 2 );
+}
+
+void PicWindow::MessageReceived( BMessage * msg )
+{
+ switch( msg->what )
+ {
+ case MSG_PREV:
+ case MSG_NEXT:
+ case MSG_WIDTH:
+ case MSG_HEIGHT:
+ case MSG_RADIO:
+ fView->HandleMessage( msg );
+ break;
+
+ case MSG_CLOSE:
+ Lock();
+ Quit();
+ break;
+
+ default:
+ BWindow::MessageReceived( msg );
+ }
+}