Kivy: How to use toggle button to lock scaling and translation of an image in scatter layout? - python-2.7

This has probably a very simple solution but I'm new to Kivy and I can't figure it out:
I use scatter layout to hold image in the application so I can scale and move it, however I woild like to implement an option to lock scaling and transformation with toggle button so it would be available again when I "unpress" the button.
No errors are returned however the scaling still works.
I'm working on this combining python and KV file.
py code:
class ScreenStartMapping(Screen):
image_path = StringProperty('')
do_scale = BooleanProperty()
def mapLine(self, *args):
if args[1] == "down":
print args[1]
self.do_scale = False
print self.do_scale
elif args[1] == "normal":
print args[1]
self.do_scale = True
print self.do_scale
and Kivy file defining entire screen:
<ScreenStartMapping>:
GridLayout:
id: gl
rows: 2
ScatterLayout:
id: sl
do_rotation: False
do_scale: toggleMappingMode
auto_bring_to_front: False
Image:
source: root.image_path
canvas:
Line:
Label:
size_hint_x: 1
size_hint_y: 0.1
canvas.before:
Color:
rgb: .1,.1,.1
Rectangle:
pos: self.pos
size: (root.size[0], root.size[1]/10)
Button:
background_color: (1.0, 0.0, 0.0, 0.5)
pos: self.pos
size: (root.size[0]/5, root.size[1]/10)
text: "Back"
font_name: "C:\WINDOWS\Fonts\segoescb.ttf"
on_press: root.manager.current = "screen1"
ToggleButton:
id: toggleMappingMode
background_color: (0.0, 1.0, 0.0, 0.5)
pos: (root.size[0]/5, self.pos[1])
size: (root.size[0]/5, root.size[1]/10)
text: "Draw line"
font_name: "C:\WINDOWS\Fonts\segoescb.ttf"
on_state:
root.mapLine(*args)
Thank you very much for your help would also appreciate any suggestions how to make this better .

So problem solved. As I thougt it was very basic beginner problem with me not knowing how exacly access the property in second widget from first.

Related

Attributed string image replacing text in UItextview

I got an attributed string with an image in a textview, the attributed image is displaying fine. The issue is whenever I add the image it replaces the text inside the textview. I want to add the attributed image and then place the cursor at the end of the image, so that i can add text below the image. This is what I tried so far, thank in advance.
let attachment = NSTextAttachment()
attachment.image = selectedImage
let newImageWidth = (textView.bounds.size.width - 10 )
let scale = newImageWidth/(selectedImage.size.width)
let newImageHeight = selectedImage.size.height * scale
attachment.bounds = CGRect(x: 0, y: 0, width: newImageWidth, height: newImageHeight)
let myAttributedString = NSAttributedString(attachment: attachment)
textView.textStorage.insert(myAttributedString, at: textView.selectedRange.location)
I fixed my issue my creating an NSMutableAttributedString() and add a new line attribute to put cursor to the bottom of the image. Hope this help someone.
var mutableAttrString = NSMutableAttributedString()
let attachment = NSTextAttachment()
attachment.image = selectedImage
let newImageWidth = (textView.bounds.size.width - 10 )
let scale = newImageWidth/(selectedImage.size.width)
let newImageHeight = selectedImage.size.height * scale
attachment.bounds = CGRect(x: 0, y: 0, width: newImageWidth, height: newImageHeight)
let myAttributedString = NSAttributedString(attachment: attachment)
let text:[String:Any] = [NSFontAttributeName:UIFont.boldSystemFont(ofSize: 20)]
// Fixed my problem of having image replacing text, instead I place the text at the bottom of the image
let textAttr = NSMutableAttributedString(string: "bottom of image \n", attributes: text)
mutableAttrString.append(myAttributedString)
mutableAttrString.append(textAttr)
textView.attributedText = mutableAttrString

Creating a D-pad in Kivy (constrain movement)

I am very new to using Kivy for an assignment and I am stumped on one specific issue. My goal is to create a directional pad as shown in the image below whereby the blue circle will start out at the center of the image and is able to be dragged, but the circle can only travel in the directions imaged by the arrows(up, down, left, right) and cannot go further than the arrows. Right now, I am only concerned with the graphical layout so what I have done is simply a widget with drag behaviour below. Is there some way that could constrain the movements of the circle?
Image:
The current achievable graphical layout for the d-pad
Python code:
from kivy.uix.widget import Widget
from kivy.uix.behaviors import DragBehavior
from kivy.app import App
class Circle(DragBehavior, Widget):
def on_touch_move(self, touch):
tx, ty = touch.pos
sx, sy = self.pos
return super(Circle, self).on_touch_move(touch)
class Test(Widget):
pass
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()
Kivy file:
<Circle>:
size: 100,74
drag_rectangle: self.x+36, self.y+28, 16, 25
drag_timeout: 10000000
drag_distance: 0
canvas:
Color:
rgba: 0,0,1,.5
Ellipse:
pos: self.pos
size: self.size
<Test>:
canvas.before:
Color:
rgba: 1,1,1,1
Rectangle:
size: root.width,root.height
pos: 0,0
canvas:
Color:
rgba: 1,1,1,1
Rectangle:
size: root.width,root.height
pos: 0,0
source: 'icons/XY_bar.png'
Circle:
pos: root.width/2.3,root.height/2.25
This is just some hints the blue circle is not exactly restricted to the axes
.py
from kivy.uix.widget import Widget
from kivy.uix.behaviors import DragBehavior
from kivy.app import App
from kivy.properties import ObjectProperty, NumericProperty
from kivy.clock import Clock
class Circle(DragBehavior, Widget):
def on_touch_move(self, touch):
if self.collide_point(*touch.pos):
if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
return super(Circle, self).on_touch_move(touch)
elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
return super(Circle, self).on_touch_move(touch)
def on_touch_down(self, touch):
if self.collide_point(*touch.pos):
if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
return super(Circle, self).on_touch_down(touch)
elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
return super(Circle, self).on_touch_down(touch)
def on_touch_up(self, touch):
if self.collide_point(*touch.pos):
if self.parent.redliney <= touch.pos[1] <= self.parent.redliney + 100:
return super(Circle, self).on_touch_up(touch)
elif self.parent.greenlinex <= touch.pos[0] <= self.parent.greenlinex + 100:
return super(Circle, self).on_touch_up(touch)
class Test(Widget):
c = ObjectProperty()
joystick_x = NumericProperty(0)
joystick_y = NumericProperty(0)
redlinex = NumericProperty(0)
redliney = NumericProperty(0)
greenlinex = NumericProperty(0)
greenliney = NumericProperty(0)
def __init__(self, **kwargs):
super(Test, self).__init__(**kwargs)
Clock.schedule_interval(self.update, 1/10.0)
def update(self, *args):
self.joystick_x = self.c.pos[0]
self.joystick_y = self.c.pos[1]
class TestApp(App):
def build(self):
return Test()
if __name__ == '__main__':
TestApp().run()
kv
<Test>:
c: c
redlinex: self.pos[0] + self.size[0]/8.0
redliney: self.pos[1] + self.size[1]/2.0 - 50
greenlinex: self.pos[0] +self.size[0]/2.0 - 50
greenliney: self.pos[1] + self.size[1]/8.0
canvas.before:
Color:
rgba: 1,1,1,1
Rectangle:
size: self.size
pos: self.pos
Color:
rgba: .75,.75,.75,1
Ellipse:
pos: root.joystick_x - 50, root.joystick_y - 50
size: 200, 200
Color:
rgba: 1,0,0,1
Rectangle:
pos: root.redlinex, root.redliney
size: 3 * self.size[0]/4.0, 100
Triangle:
points: root.redlinex, root.redliney, root.redlinex - 50, root.redliney + 50, root.redlinex, root.redliney + 100
Triangle:
points: root.redlinex + 3 * self.size[0]/4.0, root.redliney, root.redlinex + 3 * self.size[0]/4.0 + 50, root.redliney + 50, root.redlinex + 3 * self.size[0]/4.0, root.redliney + 100
Color:
rgba: .33, .51, .21, 1
Rectangle:
pos: root.greenlinex, root.greenliney
size: 100, 3 * self.size[1]/4.0
Triangle:
points: root.greenlinex, root.greenliney, root.greenlinex + 50, root.greenliney - 50, root.greenlinex + 100, root.greenliney
Triangle:
points: root.greenlinex, root.greenliney + 3 * self.size[1]/4.0, root.greenlinex + 50, root.greenliney + 3 * self.size[1]/4.0 + 50, root.greenlinex + 100, root.greenliney + 3 * self.size[1]/4.0
Circle:
canvas:
Color:
rgba: .16, .25, .6, 1
Ellipse:
pos: self.pos
size: self.size
id: c
pos: root.pos[0] + root.size[0]/2.0 - 50, root.pos[1] + root.size[1]/2.0 - 50
size: 100, 100
drag_rectangle: self.x, self.y, self.width, self.height
drag_timeout: 10000000
drag_distance: 0
Outputs

Colored text console output in Rebol

In some languages I can put Esc codes around text to make them colored on Linux console/terminal. However, this does not seem to work in Rebol:
NORMAL: "\e[0m"
RED: "\e[0;31m"
print rejoin["\e[0;31m" "red text" "\e[0m"]
Above code only produces black (usual colored) text output:
\e[0;31mred text\e[0m
Can colored text output be printed with Rebol on Linux terminal?
You can similarly use colour codes in Rebol/Red.
print "This text is ^[[0;31mred^[[0m text."
#"^[" is the Escape character in Rebol/Red.
You can, for example, change the prompts in Red with the following codes:
system/console/prompt: "^[[31m^[[5D>>^[(B^[[m "
system/console/result: "^[[32m^[[5D==^[(B^[[m"
In the Ren-C branch of Rebol 3 you can change the prompts with the following (similar) codes:
system/console/prompt: "^[[31m^[[5D>>^[(B^[[m "
system/console/result: "^[[32m^[[5D==^[(B^[[m "
REBOL [
Title: "colorebol"
Date: 14-Jul-2013
File: %colorebol.reb
Version: 1.0.0
Purpose: "Enable switching of terminal font colors and backgrounds etc"
Note: "Includes the clr func for clearing the screen"
]
clr: does [prin "^(page)"]
coloreb: func [
{Use Fore/Red /Green /Yellow /Blue /Magenta /Cyan /White /Reset and even /Black. Viola! Font-color
Similarly Background/Blue etc..., then Style/bright /dim /normal /reset_all and finally Cyclor, which
randomly picks a font color. It needs some polishing}
][cyclor print ["this is all i do. that, and provide a help doc-string"] cyclor]
Fore: make object! [
Colors: ["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" "reset"]
BLACK: does [prin "^[[30m"]
RED: does [prin "^[[31m"]
GREEN: does [prin "^[[32m"]
YELLOW: does [prin "^[[33m"]
BLUE: does [prin "^[[34m"]
MAGENTA: does [prin "^[[35m"]
CYAN: does [prin "^[[36m"]
WHITE: does [prin "^[[37m"]
RESET: does [prin "^[[39m"]
]
Background: make object! [
Colors: ["black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" "reset"]
BLACK: does [prin "^[[40m"]
RED: does [prin "^[[41m"]
GREEN: does [prin "^[[42m"]
YELLOW: does [prin "^[[43m"]
BLUE: does [prin "^[[44m"]
MAGENTA: does [prin "^[[45m"]
CYAN: does [prin "^[[46m"]
WHITE: does [prin "^[[47m"]
RESET: does [prin "^[[49m"]
]
Style: make object! [
Styles: ["bright" "dim" "normal" "reset_all"]
BRIGHT: does [prin "^[[1m"]
DIM: does [prin "^[[2m"]
NORMAL: does [prin "^[[22m"]
RESET_ALL: does [prin "^[[0m"]
]
cyclor: func [] [fore/(to-word fore/colors/(random/only [2 3 4 5 6 7 8]))]
Put this in your other script files:
do %colorebol.reb
and then use it like so:
col: has [
"Wrap the colorebol.reb wrappers to reduce visual clutter"
color /red /green /blue /yellow /cyan /magenta /black /white][
if red [color: 'red]
if green [color: 'green]
if blue [color: 'blue]
if yellow [color: 'yellow]
if cyan [color: 'cyan]
if magenta [color: 'magenta]
if black [color: 'black]
if white [color: 'white]
if unixy-os? [fore/(color)]
]
;test it:
col/magenta print "magenta" ;(it works). Maybe just mod /%colorebol.reb?
I'm not that fluent in Rebol - I'm sure there is a more concise way. But this has worked for me very well on GNU/Linux. To keep scripts portable I have an OS-detection function and the colorizing code is dependent on it.

CAShapeLayer dashed line clipping at end of view

Okay so I'm trying to draw a dashed line inside of a view, which should be fairly simple but no matter what I've tried I keep getting the dashes at both ends clipping and I would like to have the dash not have any clipped segments. Here's the extension I made (the purple background color is just there so I can see the frame)
extension UIView {
public func addDashedLineToView(_ color : UIColor) {
self.backgroundColor = UIColor.purple
let cgColor = color.cgColor
let shapeLayer: CAShapeLayer = CAShapeLayer()
let frameSize = self.frame.size
let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height)
shapeLayer.bounds = shapeRect
shapeLayer.position = CGPoint(x: frameSize.width / 2, y: frameSize.height)
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.strokeColor = cgColor
shapeLayer.lineWidth = 6
shapeLayer.lineCap = kCALineCapRound
shapeLayer.lineJoin = kCALineJoinRound
shapeLayer.lineDashPattern = [8, 10]
let path: CGMutablePath = CGMutablePath()
path.move(to: .zero)
path.addLine(to: CGPoint(x: self.frame.width, y: 0))
shapeLayer.path = path
self.layer.addSublayer(shapeLayer)
self.layer.masksToBounds = true
}
and here's a screenshot of what it ends up looking like.
not sure where I'm messing up here, but I know that I must be doing something wrong since it shouldn't be this hard to draw a dashed line in swift (I hope).
You can adjust the start position of the pattern with lineDashPhase. Try
shapeLayer.lineDashPhase = -4

Why is friction not applied when two nodes come into contact? Swift

This is the code I have for the two nodes. Declarations not included.
//paddle node and its physicsbody
paddle = childNode(withName: "paddle") as! SKSpriteNode
paddle.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: paddle.size.width,
height: paddle.size.height))
paddle.physicsBody?.isDynamic = false
paddle.physicsBody?.affectedByGravity = false;
paddle.physicsBody?.friction = 100
paddle.physicsBody?.restitution = 0
//paddle.physicsBody?.linearDamping = 1
//paddle.physicsBody?.angularDamping = 1
//Second node
rect.position = CGPoint(x: 100, y:500)
rect.fillColor = UIColor(hue: 215/360, saturation: 49/100, brightness: 54/100, alpha: 1.0)
rect.strokeColor = UIColor(hue: 215/360, saturation: 49/100, brightness: 54/100, alpha: 1.0)
rect.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: rect.frame.width, height: rect.frame.height))
rect.physicsBody?.friction = 0.4
rect.physicsBody?.restitution = 0
rect.physicsBody?.mass = 100
rect.physicsBody?.allowsRotation = true
rect.physicsBody?.isDynamic = true
rect.physicsBody?.linearDamping = 0
rect.physicsBody?.angularDamping = 0
//rect.physicsBody?.velocity = CGVector(dx: 0, dy: -700)
rect.physicsBody!.applyImpulse(CGVector(dx: 2.0, dy: -2.0))
rect.lineWidth = 10
addChild(rect)
I am not sure if I am asking the right question but I have the rectangular node falling down unto a paddle that can be moved side to side by touch. Once the rect node is on top of the paddle I want it to stay on it while the I move the paddle but it stays pinned and does not move although everything else (gravity, rotation, etc.) works.
Here are the pictures to clarify
https://i.stack.imgur.com/LIqYT.png
https://i.stack.imgur.com/ap6Yy.png