Set/display percentages in rulers

Previous topic - Next topic

Edradour

Hello
Is there any way to show percentages of page size in the rulers?
Personally, I find it easier to relate to a page width of 100% rather than (say) 280.63 pt or 99 millimeter.

a.l.e

hi edradour

i think, i've already seen your question somewhere else but i cannot recall where... and if i replied to it.

basically: i don't think that your wish makes sense.

can you explain us why you would do that?

fyi, in scribus you can set the measurement in percents, which is very handy from time to time... or use guide columns (which is often a very useful feature!)

ciao
a.l.e

Edradour

Thanks
"fyi, in scribus you can set the measurement in percents, which is very handy from time to time... or use guide columns (which is often a very useful feature!)"

I think that's what I intended asking for, how to set measuments in percentages.  It is something I often did in InDesign, reading the percentages from the rulers to measure where to set my guides.

(e.g. full page height = 100%, full page width = 100% - but they are not necessarily equal in fixed length measurments (mm, inch, pixel &c))

a.l.e

if you want an frame to fill a page, just shift+click (instead of simply clicking) when creating it and it will occupy the whole space around the cursor, up to the first guide or margin.

if you want to extend an existing frame to the right margin, just activate the snapping to guides (it should (almost) always be on... of cours) and pull it there.

if you want to regularly create frames that fills half of the page, you should of course put a column guide (see the guides manager)...
and if it's only about one single frame, you can use the shift-click to fill the page and then change the width of the frame to be "50%" or "width/2".
and if you want a 1 cm gutter in the middle, set it to "width / 2 - .5cm".

Edradour

OK, I've written a simple Python script with user interface to generate the grid lines I'd want.

I'd be happy to share it (and receive critique), if there was an obvious place to do so.


a.l.e

you can paste it here...

if you think it can be of general interest, you can share it in the wiki... (http://wiki.scribus.net)

glad you found a solution that works for you!

Edradour

#6
OK, here:



#!/usr/bin/env python
# -*- coding: utf-8 -*-

#############################################
##
##   A script to set guide lines at equal intervals across and down the page to help facilitate layout design.
##
##   Users are asked to:
##      enter the number of spaces in either direction (one more than the number of guide lines),
##      whether they want to remove existing guide lines
##      and whether to effect changes work on a single page, or the whole document.
##
##   Note: no guide line will be created for less than two (2) horrizontal or vertical panels
##   Warning: this script may be used to clear all guide lines
##
##############################################
##
##   based on [PROGRAM FILES]/[SCRIBUS 1.4.7]/share/samples/boilerplate.py
##
##############################################

import sys

try:
   # Please do not use 'from scribus import *' . If you must use a 'from import',
   # Do so _after_ the 'import scribus' and only import the names you need, such
   # as commonly used constants.
   import scribus as sc
except ImportError,err:
   print "This Python script is written for the Scribus scripting interface."
   print "It can only be run from within Scribus."
   sys.exit(1)

#########################
# YOUR IMPORTS GO HERE  #
#########################
try:
   import Tkinter as tk
   from tkFont import Font
except ImportError:
   print "This script requires Python's Tkinter properly installed."
   sc.messageBox('Script failed',
            'This script requires Python\'s Tkinter properly installed.',
            ICON_CRITICAL)
   sys.exit(1)

# added ras
   
# set initial values, klunky to use globals, but ...
#    commented out parameters - possible suggestions for future use, but not yet implemented
params = {
    'horrizontal': 0,      # arbitrary, should be zero in production
    'vertical' : 0,      # arbitrary, should be zero in production
    #'hvLocked' : True,
    'allPages' : False,   # False -> only muck up one page at a time
    'clearExistingGuides' : False,   # easier to re-run than to re-insert lost guides
    #'resetMargins' : True,
    #'applyToMaster' : False,
    #'gutter' : False,      # or may be a float number would be better ???
    #'spreadAware' : False,   # for gutter
    'result' : False,      # do not display result, used to check which button, OK, or Cancel was pressed.
    }
   
# set params fields order (we wouldn't need this in Python 3.x),
# used to sort the UI display fields ... change the key to change sequence
orderby = {
    10 : 'horrizontal',
    20 : 'vertical',
    30 : 'hvLocked',
    40 : 'allPages',
    50 : 'clearExistingGuides',
    60 : 'resetMargins',
    70 : 'applyToMaster',
    80 : 'gutter',
    90 : 'spreadAware',
    # -1000 : 'result',   # do not uncomment, we do not need or want to display the result field
    }

# message handling & feed back
def myMessage(head, body):
   # use this for monitoring progress when debugging
   sc.statusMessage( head + ' -> ' + body )
   # comment out (or otherwise remove) the next lines for production, uncomment to see on console or to pop-up display
   # print head + ' -> ' + body + '\n'
   # sc.messageBox(head, body)

# user interface
class TkUI(tk.Frame):

    buttons = {}
    vars = {}
   
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        # self.pack()
        self.createWidgets()
        self.grid(columnspan=2)
   
    #Creation of init_window
    def createWidgets(self):
        self.winfo_toplevel().title("Set Guides")
       
        myrow = 0
        l = tk.Label(self, text = 'Set the number of panels' )
        l.grid(column=0, row=myrow, columnspan=2)
        myrow += 1
       
        #for k, v in params.iteritems():
        for o, k in sorted(orderby.items()):
            if not k in params:
               continue
           
            v = params[ k ]
   
            b = {}
            l = {}
           
            var = tk.IntVar()
            var.set( v )
            self.vars[ k ] = var
           
            if isinstance(v, (bool)):
                # trap bool types first, 'cause they are int, and we want to respond to ints too
                #
                # make a Checkbutton for yes/no answers
                b = tk.Checkbutton(self, text=k, variable=self.vars[ k ])
                b.var = var
                b.bind('<FocusOut>', self.assign )
                b.bind('<Leave>', self.assign )
                b.grid(row=myrow, column=1, sticky=tk.W)
            elif isinstance(v, (int)):
                # make a data entry field for other integer entries
                l = tk.Label(self, text = k )
                l.grid(column=0, row=myrow, sticky=tk.E)
               
                b = tk.Entry(self, textvariable=var)
                b["text" ] =  k
                b.grid(column=1, row=myrow, sticky=tk.W)
                b.bind('<FocusOut>', self.assign )
                b.bind('<Leave>', self.assign )
            else:
                # we are in trouble
                sc.messageBox("Unexpected type", 'Unexpected type for:\n' + k + ' -> ' + str(v))
                continue
           
            self.buttons[ k ] = b
            myrow += 1
       
        self.okButton = tk.Button(self, text="OK", command=self.ok)
        self.okButton.grid(column=0, row=myrow, sticky=tk.S, padx=10, ipadx=30)
       
        self.cancelButton = tk.Button(self, text="Cancel", command=self.cancel)
        self.cancelButton.grid(column=1, row=myrow, sticky=tk.S, padx=10, ipadx=30)
   
    def assign( self, event ):
        self.doAssign( event.widget )
        #try:
        #    self.doAssign( event.widget )
        #    # params[ event.widget['textvariable'] ] = int(event.widget.get())
        #except:
        #    pass
   
    def doAssign(self, widget ):
        try:
            params[ widget['textvariable'] ] = float(widget.get())
            return
        except:
            pass
       
        try:
            txt = widget['text']
            params[ txt ] = bool( self.vars[ txt ].get() )
            return
        except:
            pass
   
    def ok( self ):
        # OK button pressed
        # make sure each field is read
        #   - this does not always happen just moving around the form.
        for k, b in self.buttons.items():
            self.doAssign( b )
        params[ 'result' ] = True
        self.quit()
   
    def cancel( self ):
        # cancel button pressed
        params[ 'result' ] = False
        self.quit()

def setParameters():
   myMessage('in getSetParameters','need to define actions')
   """ Application/Dialog loop with Scribus sauce around """
   try:
      myMessage('getSetParameters', 'Running script...')
      sc.progressReset()
      root = tk.Tk()
      app = TkUI(root)
      app.mainloop()
      root.destroy()
     
   finally:
      if sc.haveDoc() > 0:
         sc.redrawAll()
      myMessage('getSetParameters', 'Done.')
      sc.progressReset()
   
   myMessage('returning from getSetParameters','need to define actions')
   # return params;
   return params[ 'result' ];

def setGuides():
   myMessage('in setGuides','need to define actions')
   result = setParameters()
   # bo = params[ 'bool' ]
   # it = params[ 'int' ]
   
   myMessage('setGuides', 'result = ' + str( result ))
   
   if result:
       pass
   else:
       return
   
   p = "Parameters:\n"
   for k, v in params.items():
      p += "\n" + k + ' -> ' + str( v )
   # for k, v in bo.items():
   #   p += "\n" + k + ' -> ' + str(v)
   
   p += '\n\nnow, do actions'
   myMessage('in setGuides', p)
   
   curPg = sc.currentPage()
   if params[ 'allPages' ]:
      pg = 0
      pgs = sc.pageCount()
   else:
      pg = curPg - 1
      pgs = curPg
   
   while pg < pgs:
      pg += 1
      sc.gotoPage( pg )
      pgSize = sc.getPageNSize( pg )
      # print 'pgSize -> ' + str(pgSize) + '\n'
      # width   pgSize[ 0 ]
      # height   pgSize[ 1 ]
     
      h = []
      w = []
      v = int( params[ 'horrizontal' ] )
      # v = float( params[ 'horrizontal' ] )  # float can give 'interesting' results
      stp = 1
     
      while stp < v : # width
         w.append( stp * pgSize[ 0 ] / v )
         stp += 1
     
      v = int( params[ 'vertical' ] )
      #v = float( params[ 'vertical' ] )  # float can give 'interesting' results
      stp = 1
      while stp < v : # width
         h.append( stp * pgSize[ 1 ] / v )
         stp += 1
     
      if params[ 'clearExistingGuides' ]:
         sc.setHGuides( h )
         sc.setVGuides( w )
      else:
         sc.setHGuides(sc.getHGuides() + h )
         sc.setVGuides(sc.getVGuides() + w )
   
   # return focus to current page
   sc.gotoPage( curPg )
   return

# end added ras

def main(argv):
   """This is a documentation string. Write a description of what your code
   does here. You should generally put documentation strings ("docstrings")
   on all your Python functions."""
   
   setGuides()      # changed ras

def main_wrapper(argv):
   """The main_wrapper() function disables redrawing, sets a sensible generic
   status bar message, and optionally sets up the progress bar. It then runs
   the main() function. Once everything finishes it cleans up after the main()
   function, making sure everything is sane before the script terminates."""
   try:
      sc.statusMessage("Running script...")
      sc.progressReset()
      main(argv)
   finally:
      # Exit neatly even if the script terminated with an exception,
      # so we leave the progress bar and status bar blank and make sure
      # drawing is enabled.
      if sc.haveDoc():
         sc.setRedraw(True)
      sc.statusMessage("")
      sc.progressReset()

# This code detects if the script is being run as a script, or imported as a module.
# It only runs main() if being run as a script. This permits you to import your script
# and control it manually for debugging.
if __name__ == '__main__':
   main_wrapper(sys.argv)



Note: if you copy/paste this code to the Scribus console, it may complain about indents.
For each blank line, make sure ther are as many spaces as precede the next line of code below - this should stop the complaints.

a.l.e

a simple comment from me, before running the script:

i would remove

#!/usr/bin/env python

it does nothing and might mislead people into thinking that they can run your script outside of scribus...

now, i'll try  to run it... but i'm not sure, i have tk installed... i will have to check...
i'm curious too see what it looks like...
i cannot guess by just looking at the code...

a.l.e

#8
i got it to run... you seem to have done the same as is already in "page > manage guides | columns and rows" ....



or am i missing something?

and for the small details:

- "horizontal", not "horrizontal" : - )

[attachment deleted by admin]

Edradour

Yes, looks very similar - if I'd known it existed or where to find it.

The built in page > manage guides does more than my routine, and does it better.

"horrizontal" - if that's my only spelling mistake, I'm doing well ...

Thanks

a.l.e

hi edradour...

well, i've tried to give you a hint ("put a column guide (see the guides manager)") ... but it's often hard to know, how much the reader already knows about scribus already, how long a post should be, and  how much time i should invest into it...

you have created a nice script, and probably learned a few things: i hope you will be able to create more script to improve your workflow!

ciao
a.l.e