I have a flash file I want to programatically find the dimensions of in my code. Right at the beginning of the code I have the string:
[SWF(width='700', height='500')]
And several subclasses later I want to pull these "700" and "500" values up as variables.
Is there a way to find this?
I've tried referencing this.width and this.height but they always end up zero for the parent canvas.
Referencing the Stage does not work as it returns the current stage size, not the desired size. For example, if I load the SWF directly and not through a browser, I can scale the viewport to be as big or small as I like.
stage.stageWidth and stage.stageHeight will refer to the full width and height of the stage. It will change at runtime if the instance of Flash Player changes size. There's also loaderInfo.width and loaderInfo.height, which should tell you the original values specified in the [SWF] metadata, and they won't change at runtime.
Related
Basically I've got a QGridLayout with a few widgets in it. The important ones are 2 labels, which I use for drawing images to the screen. Well, if the user wants, he can change the resolution of the incoming images, thus, forcing the Labels to resize.
Let's assume the initial size of the label is 320x240. The user changes the VideoMode to 640x480, the label and the entire GUI resizes perfectly. But when the user switches back to 320x240, the label shrinks, but the Layout/Window does NOT.
I've played around with sizePolicies and sizeHints, and resize(0,0), but nothing did the trick. Could somebody help me with this?
Here some screenshots to clarify the problem:
You need to set the size constraint of the layout holding all your widgets to "SetFixedSize". Although the name doesn't sound like it will work, it ensures that your layout will only use the space it needs. You will not have the problem like you do in your second screenshot.
Example:
mainLayout.setSizeConstraint(QLayout::SetFixedSize);
QLayout::setSizeConstraint(QLayout::SetFixedSize) solves this problem well when you prefer keeping your widget's size fixed at all times--that is, if you'd like it to always be fixed to its "packed" size (which may still vary as the child widgets change size). That is what the "fixed" means there: "fixed" to the correct size, even as the latter varies. (In Qt terms, what I'm calling the "packed" size is simply the widget's sizeHint.)
But a constraint may be too strong a solution in some instances. In particular, if you apply it to a top-level window, then the user will not be free to resize the window. If you don't like that, you can instead perform the "set size to sizeHint" operation instantaneously each time it's needed, rather than imposing it as an unrelenting constraint. The way to do that is to call QWidget::adjustSize().
http://doc.qt.io/qt-5/qwidget.html#adjustSize
Note that if the container whose children are changing size is not the top-level window, then adjustSize() may have to be called recursively on the container and its parents. (In my case I had to do that, anyway. I also tried the size-constraint scheme, and found that applying the constraint at only the topmost level was successful in compacting all levels. I haven't enough knowledge of Qt to comment usefully on these observations, so I merely share them.)
You need to store the original size of your widget parent window before applying any changes to the layout and restore it when the user switches back to the original.
Notice that you need to work with the widget parent window size and not the widget parent size.
in your widget before applying the layout changes:
minimumWindowSize = this->window().size();
when you finished reorganizing the widget to the compact size
this->window().resize(minimumWindowSize);
So that is exactly what i'm doing in mu project.
Resolution os doesn't matter. I have only to have a widget for rendering video, or image in your case.
void MainWindow::resizeEvent(QResizeEvent* event)
{
QMainWindow::resizeEvent(event);
if ((player != 0) && ((player->isPlaying()) || player->isLoaded() || player>isLoaded())){
renderer->resize(ui->mainVideoWidget->width(),ui->mainVideoWidget->height());
resizeFilter();
}
}
I'm trying to write my flex application so that it restores the user's settings when it starts up. The application has 3 data grids (only one is visible [on screen] at any time) and I simply save the state of the grids if the user ever does any resize events.
Saving the state works perfectly, the problem comes when restoring. It seems that only the visible data grid gets restored properly. On all the other grids, the widths are all wrong and do not match the settings I restored from.
The problem is that, when the application starts, the data grids are not sized correctly. Each data grid takes up the full screen, but initially they are only given a very small size (ie. 200 width)
Is there some way to force the data grid to resize properly when it is created? Or is it possible to know when the data grid is "maximized" I don't want to hook up to the resize event - if possible - because I would get that quite frequently, and I only want to restore the settings once.
Here's the code I'm using to restore the column widths:
var grid:DataGrid = ...;
... for each column ...
... parse width into width (ie. width is now "320")
// If it's in the config, it's visible
col.visible = true;
col.width = width;
... After loop ...
grid.invalidateSize();
grid.invalidateDisplayList();
Edit:
Here's the info you guys requested:
The settings are saved into a database (the flex proejct is connected to JBoss). I simply save a CSV type thing with the column's name and it's width. I know this works because the one data grid that is visible when the application starts gets sized correctly.
Yes, the grids use relative sizes (ie. 100%) -- I can't really change that because I want the grid to take up all available space in its container -- and I want the user to be able to resize their browser and still have it look right.
Each grid is contained in its own Hbox
The data grids are created when the application starts -- you can only see one of them though. They are in a tab navigator type thing, but it's creation policy is set to "all" so they can be populated with data (the population takes some time, and typically the user sits on the front grid for a little while.)
I can't put my resize stuff in the creationComplete handler because I end up with the same problem. The grid's size is like 50 right after it's created (it should be like 1000, 100% of the page width) -- and then I go to set the sizes of the columns (which are obviously > 50) and the resize does nothing
A couple thoughts:
Resize during CreationComplete(): When are your datagrids being created? Can you declare a method like resizeDataGrid() when the creationComplete() event fires for the datagrid? If you are using datagrids in, say, a TabNavigator, the default creation policy is to delay component creation until the user uses the component (e.g. makes the tab active).
Fixed Sizes: Are your datagrids using a fixed size, or a relative size? Relative sizing (e.g. width='50%') of a datagrid or datagrid columns is buggy in Flex, and the best workaround is to set a pixel width of both the datagrid and the datagrid columns
Storing User Preferences: How are you storing your user preferences? Using a SharedObject to store datagrid widths is probably the best option.
Spark Containers: How are the datagrids contained? For example, do they each sit within a VGroup, or are they not contained at all? I've found that using Spark layout tools (like a VGroup) to contain your datagrids improves datagrid layout issues.
What we did was saved off the column width on initialization and then reset the widths on rerender of the grid, this will occur on the first draw of the grid and subsequent resizes.
the only problem with this was that it requires columns to be resizable but does not allow the user to resize
// saves column width - this is intended to save width percent which
// will only be available on initialization, after that I beleive widths
// will be fixed size
private function saveOffColumnWidths(columns:ArrayCollection):void
{
for each(var column:TDMSEDataGridColumn in columns)
{
originalColWidths.push(column.width);
}
}
// resets the column widths - the saved widths are assumed to be width percentages
private function resetColumnWidths():void
{
dataGrid.columns[0].width=20; // set the check col seperately
for (var pos:int=0; pos<dataGrid.columnCount-1;pos++ )
{
dataGrid.columns[pos+1].width = (dataGrid.width - 20) * originalColWidths[pos];
}
}
protected function dataGrid_renderHandler(event:Event):void
{
resetColumnWidths();
}
I have an application where I try to load an external SWF. So, we have:
My application: The Stage's dimensions are 768x1280. ScaleMode = EXACT_FIT.
External SWF: It's another application where its stage is: 800x600. ScaleMode = EXACT_FIT.
The problem is that the external SWF does not modify its size although I apply "scaleX, scaleY", change its width and so on.
I also tried to insert it into a Canvas container (as "How to resize an external SWF to fit into a container?" ) but it didn't solve my problem.
The interesting piece of code is when the external SWF is loaded by my application:
private function onLoadedApp( evt:Event ):void{
stage.scaleMode = StageScaleMode.EXACT_FIT;
trace("Loading Application..");
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
loaderInfo.removeEventListener( Event.COMPLETE, onLoadedApp);
trace(loaderInfo.loader.content);
var swfApplication:SpriteUIComponent = new SpriteUIComponent(evt.target.loader.content );
if( SWFContainer.width < swfApplication.explicitWidth ){
var coef:Number = SWFContainer.width/swfApplication.explicitWidth;
swfApplication.scaleX = coef;
swfApplication.scaleY = swfApplication.scaleX;
}
SWFContainer.addElement(swfApplication);
}
I also tried to do it through SWFLoader, but the external.swf's content doesn't change its original size although I add the "scaleContent" parameter.
Visual results I got:
The external SWF is loaded on the suitable position and it "seems" to have 320x240 dim. But its width is a bit cropped, since if I stretch the Flash Player I achieve to see the rest of the external swf's stage. Besides, the external SWF never is resized although I shrink/stretch the Flash Player. It always remains fixed (if I trace its dimensions, I always get 800x600, although I visually see 320x240)- If I increase the stage's width of the main application, this little clip dissapear.
Discussion:
I know the original Stage's dimensions are 800, and this is greater than the original stage of my application (768), but I think, when I do the resizing, external SWF's Stage have to be fitted in the container. It is fitted, but a part of the external SWF is not seen. It's like Flash Player remembered that the external SWF Stage's width were greater than my application's one...
Thanks in advance.
Even with scaleContent set to "true" you still need to set an exact height and width to the SWFLoader control for it to even try resizing the internal SWF. All scaleContent does is instead of showing the SWF at regular or stretched sizes, it also up-scales the SWF if needed, and if not just scales it to retain the ratio of the original SWF.
I don't think the issue is with your ScaleMode. There can only be one Stage per flash player. The "stage" property of your 'external' SWF references the Stage of your 'application' SWF after it's added to the display list. If the SWF is loaded and not added to the display list, the loaded SWF's 'stage' property will equal 'null'. Setting the stage scaleMode inside your external SWF won't dictate how it scales once loaded into another SWF.
Also, you're probably resizing the SWFContainer, not the SWF itself...thats why the SWF width and height properties are always 800x600. I'm not sure if this is what you're asking for, but from what I'm understanding, you may need to create a stage resize event listener.
Have you tried to use a scale effect on "External SWF"?
Scale Effect
I have an application where I try to load an external SWF. So, we have:
My application: The Stage's dimensions are 768x1280. ScaleMode = EXACT_FIT.
External SWF: It's another application where its stage is: 800x600. ScaleMode = EXACT_FIT.
The problem is that the external SWF does not modify its size although I apply "scaleX, scaleY", change its width and so on.
I also tried to insert it into a Canvas container (as "How to resize an external SWF to fit into a container?" ) but it didn't solve my problem.
The interesting piece of code is when the external SWF is loaded by my application:
private function onLoadedApp( evt:Event ):void{
stage.scaleMode = StageScaleMode.EXACT_FIT;
trace("Loading Application..");
var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
loaderInfo.removeEventListener( Event.COMPLETE, onLoadedApp);
trace(loaderInfo.loader.content);
var swfApplication:SpriteUIComponent = new SpriteUIComponent(evt.target.loader.content );
if( SWFContainer.width < swfApplication.explicitWidth ){
var coef:Number = SWFContainer.width/swfApplication.explicitWidth;
swfApplication.scaleX = coef;
swfApplication.scaleY = swfApplication.scaleX;
}
SWFContainer.addElement(swfApplication);
}
I also tried to do it through SWFLoader, but the external.swf's content doesn't change its original size although I add the "scaleContent" parameter.
Visual results I got:
The external SWF is loaded on the suitable position and it "seems" to have 320x240 dim. But its width is a bit cropped, since if I stretch the Flash Player I achieve to see the rest of the external swf's stage. Besides, the external SWF never is resized although I shrink/stretch the Flash Player. It always remains fixed (if I trace its dimensions, I always get 800x600, although I visually see 320x240)- If I increase the stage's width of the main application, this little clip dissapear.
Discussion:
I know the original Stage's dimensions are 800, and this is greater than the original stage of my application (768), but I think, when I do the resizing, external SWF's Stage have to be fitted in the container. It is fitted, but a part of the external SWF is not seen. It's like Flash Player remembered that the external SWF Stage's width were greater than my application's one...
Thanks in advance.
Even with scaleContent set to "true" you still need to set an exact height and width to the SWFLoader control for it to even try resizing the internal SWF. All scaleContent does is instead of showing the SWF at regular or stretched sizes, it also up-scales the SWF if needed, and if not just scales it to retain the ratio of the original SWF.
I don't think the issue is with your ScaleMode. There can only be one Stage per flash player. The "stage" property of your 'external' SWF references the Stage of your 'application' SWF after it's added to the display list. If the SWF is loaded and not added to the display list, the loaded SWF's 'stage' property will equal 'null'. Setting the stage scaleMode inside your external SWF won't dictate how it scales once loaded into another SWF.
Also, you're probably resizing the SWFContainer, not the SWF itself...thats why the SWF width and height properties are always 800x600. I'm not sure if this is what you're asking for, but from what I'm understanding, you may need to create a stage resize event listener.
Have you tried to use a scale effect on "External SWF"?
Scale Effect
I'm trying to print a SWF and have come across some problems.
When using the Print function in the browser, the SWF will be distorted, and not scaled correctly. So I've tried to implement a Print function using Actionscript instead.
The different approaches I've taken are:
Printing using the right click context menu of the Flash Player and choose Print. This works almost as expected, but It flattens transparent PNGs and isn't scaled correctly.
Creating a FlexPrintJob and adding the component to the job. Will not scale the component to fit the page, even though I've set FlexPrintJobScaleType.SHOW_ALL on the print job.
Creating a PrintView containing an Image. Then taking a screenshot of the component and set this as the Image in the PrintView. When this is done, I create a new FlexPrintJob and send it. This seems to work most of the times, but the scaling will distort and make small elements (like text) look really bad.
The code for printing looks like this:
var pj:FlexPrintJob = new FlexPrintJob();
if (pj.start())
{
pj.addObject(componentToBePrinted, FlexPrintJobScaleType.SHOW_ALL);
pj.send();
}
What I would like to do is to get the right click context menu to work, and by that I mean setting the scaling of the SWF. Is this possible? Are there any other alternatives when printing a SWF? What am I doing wrong?
When testing, I'm printing to a PDF, but I don't think that will change the results.
You need to scale your Print Job for what you want in FlexPrintJobScaleType:
MATCH_WIDTH
(Default) Scales the object to fill
the available page width. If the
resulting object height exceeds the
page height, the output spans multiple
pages.
MATCH_HEIGHT
Scales the object to fill the
available page height. If the
resulting object width exceeds the
page width, the output spans multiple
pages.
SHOW_ALL
Scales the object to fit on a single
page, filling one dimension; that is,
it selects the smaller of the
MATCH_WIDTH or MATCH_HEIGHT scale
types.
FILL_PAGE
Scales the object to fill at least one
page completely; that is, it selects
the larger of the MATCH_WIDTH or
MATCH_HEIGHT scale types.
NONE
Does not scale the output. The printed
page has the same dimensions as the
object on the screen. If the object
height, width, or both dimensions
exceed the page width or height, the
output spans multiple pages.
See http://livedocs.adobe.com/flex/3/html/help.html?content=printing_3.html
for more information on this.