Applying a Frame Style

From Scribus Wiki
Jump to: navigation, search
This article is part of the Scripts series.

Although frame styles do not exist as yet, one way of simulating them would be with Scripter, since we have available most if not all the commands that would be needed to accomplish something like this.

A question on the mailing list asked about whether there was some way to create and apply "frame styles", in this case meaning particular settings for columns, column gaps, and the text distances.

To be more specific:

As an example, for a newsletter project that I have been involved with, we have determined that for the A4 pages we use, 
most frames (and almost *all* text frames) should have widths in multiples of 65mm - which comprises 60mm for the text, 
and 5mm for the gap between the text and the left and right borders (ie, two 2.5mm gaps); and therefore  multi-column frames
should have the column gap set to 5mm.

And from this along with desired gaps to page edges, comes the 'correct' X-pos settings for most frames: 7.5mm, 72.5mm, 
or 137.5mm (this gives us a total gap of 10mm from page edge to left edge of the text). 
 
Hence for any frame (text or image) a single-column frame should be  65mm, a double-column frame should be 130mm, and a 
triple-column frame  should be 195mm; and should have its X-pos set to one of 7.5mm, 72.5mm  or 137.5mm. 

So taking these values as a starting point, here is an illustration of how to set up a very simple means to apply settings to a text frame. This is a very simple script, even operationally, where the only input from the user is to specify the number of columns.

Newsframe.png Newsframe1.png Newsframe2.png Newsframe3.png

What you see above are, from left to right, the starting point of a frame filling to margins on an A4 document with sample text, then running the script for 3 columns, then 2 columns, then 1 column. One can readily imagine that an option could be to specify where to position a one or two-column frame, with the one-column having 3 choices and the two-column 2 choices, but this is not what what seemed to be indicated in this mail list example. Generally, it's better to keep a script as simple as needed – it can always be made more complex later.

Note that the height and Y-Pos of the frame are not being modified.

news_frame.py

#!/usr/bin/env python
# -*- coding: utf-8  -*-
# news_frame.py
# 2011.07.04
# made for Nik Trevallyn-Jones
# 
"""
This script will convert a selected text frameto 1, 2 or 3-columns, with gap(s) of 5mm, 
textdistances of 2.5mm.

Does not check if selected object is text frame or something else.
"""
import scribusif scribus.haveDoc():
    if scribus.selectionCount() == 0:
        scribus.messageBox('Scribus - Script Error',
            "There is no object selected.\nPlease select one and try again.",
            scribus.ICON_WARNING, scribus.BUTTON_OK)
        sys.exit(2)
    if scribus.selectionCount() > 1:
        scribus.messageBox('Scribus - Script Error',
            "You have more than one object selected.\nPlease select only one and try again.",
            scribus.ICON_WARNING, scribus.BUTTON_OK)
        sys.exit(2)
    units = scribus.getUnit()
    scribus.setUnit(1) # millimeters = 1
    selectedframe = scribus.getSelectedObject()
    xpos,ypos = scribus.getPosition(selectedframe)
    width,height = scribus.getSize(selectedframe)
    columns = 0
    while (columns < 1) or (columns > 3):
        columns = scribus.valueDialog('No. of Columns','How many columns?\n(1-3)','3')
        columns = int(columns)
    if (columns == 1):
        scribus.setTextDistances(2.5,2.5,0,0,selectedframe)
        scribus.setColumns(1,selectedframe)
        scribus.moveObjectAbs(137.5,ypos,selectedframe)
        scribus.sizeObject(65,height,selectedframe)
    if (columns == 2):
        scribus.setTextDistances(2.5,2.5,0,0,selectedframe)
        scribus.setColumns(2,selectedframe)
        scribus.setColumnGap(5,selectedframe)
        scribus.moveObjectAbs(72.5,ypos,selectedframe)
        scribus.sizeObject(130,height,selectedframe)
    if (columns == 3):
        scribus.setTextDistances(2.5,2.5,0,0,selectedframe)
        scribus.setColumns(3,selectedframe)
        scribus.setColumnGap(5,selectedframe)
        scribus.moveObjectAbs(7.5,ypos,selectedframe)
        scribus.sizeObject(195,height,selectedframe)
    scribus.setUnit(units)
    scribus.redrawAll()

What we're doing here is just deciding if there is a document open, whether a frame is selected, and only one frame, after which we ask how many columns to make, with a forcing of an integer value, and that the integer must be 1, 2, or 3 for the script to complete. The script can be run recursively if desired, but you can't go back to the original version on the far left, at least with the script (I thought that Undo might manage this, but no, it doesn't).

The mail list poster indicated that he works in millimeters, so we might dispense with the getUnit() and setUnit() commands, but you have to consider that these numbers very specifically apply to millimeter units, so for safety it's best to ensure that changes are made in a millimeter scale.

Here, then, is a basic structure which one might modify to whatever needs there are, and even make some serial versions for different purposes.