Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding a message box which allows copying of text #21

Merged
merged 6 commits into from
Nov 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/version_1_1
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# This details the important differences introduced in tk_builder 1.1
# NB: bump the version number in __about__.py to reflect the below.

* .8 - Adding a messagebox which allows copying of text
* .7 - Adding image canvas tools for coordinate inspection and measurement
* .6 - Allowing initialization parameters for image canvas tools
Enable shift tool to simultaneously handle multiple geometries on the image canvas
Expand Down
2 changes: 1 addition & 1 deletion tk_builder/__about__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
'__license__', '__copyright__']


__version__ = "1.1.7"
__version__ = "1.1.8"


__classification__ = "UNCLASSIFIED" # This should be set appropriately in any high-side version
Expand Down
36 changes: 35 additions & 1 deletion tk_builder/widgets/derived_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
__author__ = "Thomas McCullough"

import tkinter
from tk_builder.widgets.basic_widgets import Frame, Scrollbar, Treeview, Text
from tkinter.simpledialog import Dialog

from tk_builder.widgets.basic_widgets import Frame, Scrollbar, Treeview, Text, Button
from tk_builder.widgets.widget_descriptors import TypedDescriptor


Expand Down Expand Up @@ -115,3 +117,35 @@ def get_value(self):

def __str__(self):
return str(self.frame)


class CopyableMessageBox(Dialog):
"""
A messagebox with copyable text
"""

def __init__(self, title, message=None, width=60, height=10, parent=None):
self.message = message
self.width = width
self.height = height
self.text = None
if parent is None:
# noinspection PyProtectedMember
parent = tkinter._default_root
Dialog.__init__(self, parent, title=title)

def body(self, parent):
self.text = Text(self, width=self.width, height=self.height)
self.text.pack(fill="both", expand=True)
self.text.insert("1.0", self.message)
self.text.configure(state='disabled')
return self.text

def buttonbox(self):
box = Frame(self)

w = Button(box, text="OK", width=10, command=self.cancel, default=tkinter.ACTIVE)
w.pack(side=tkinter.LEFT, padx=5, pady=5)
self.bind("<Return>", self.cancel)
self.bind("<Escape>", self.cancel)
box.pack()
35 changes: 31 additions & 4 deletions tk_builder/widgets/image_canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,9 +606,13 @@ def _validate_kwargs(self):
self.highlight_args['width'] = self.regular_args['width'] + 2

# perform color validation
if self._type in [ShapeTypeConstants.LINE, ShapeTypeConstants.ARROW, ShapeTypeConstants.POINT, ShapeTypeConstants.TEXT]:
if self._type in [
ShapeTypeConstants.LINE, ShapeTypeConstants.ARROW,
ShapeTypeConstants.POINT, ShapeTypeConstants.TEXT]:
attr = 'fill'
elif self._type in [ShapeTypeConstants.RECT, ShapeTypeConstants.POLYGON, ShapeTypeConstants.ELLIPSE]:
elif self._type in [
ShapeTypeConstants.RECT, ShapeTypeConstants.POLYGON,
ShapeTypeConstants.ELLIPSE]:
attr = 'outline'
else:
attr = None
Expand Down Expand Up @@ -719,7 +723,6 @@ def highlight_args(self):

return self._highlight_args


def replicate(self):
"""
Replicate the vector object, leaving the name and id unassigned.
Expand Down Expand Up @@ -939,7 +942,7 @@ def remove_shape_from_tracking(self, the_id):
"""

if the_id not in self._vector_objects:
return None # nothing to be done
return None # nothing to be done

vector_object = self._vector_objects[the_id]
if vector_object.is_tool:
Expand Down Expand Up @@ -2839,6 +2842,30 @@ def create_new_polygon(self, coords, make_current=True, increment_color=True, is

return self.create_shape_from_vector_object(vector_obj, coords, make_current=make_current)

def show_valid_data(self, valid_data_coordinates):
"""
Create or edit the valid data polygon.

Parameters
----------
valid_data_coordinates : numpy.ndarray
Of the form [[row, col]].
"""

try:
valid_data_id = self.variables.get_tool_shape_id_by_name('VALID_DATA')
except KeyError:
valid_data_id = None

image_coords = valid_data_coordinates.flatten()
if valid_data_id is None:
vector_object = VectorObject(
ShapeTypeConstants.POLYGON, name='VALID_DATA', is_tool=True, color='darkred',
regular_args={'dash': (), 'fill': ''}, highlight_args={'dash': (), 'fill': ''})
valid_data_id = self.create_shape_from_vector_object(vector_object, (0, 0, 0, 0), make_current=False)
self.modify_existing_shape_using_image_coords(valid_data_id, image_coords)
self.show_shape(valid_data_id)

# shape as geometry methods
def get_geometry_for_shape(self, shape_id, coordinate_type='image'):
"""
Expand Down
32 changes: 10 additions & 22 deletions tk_builder/widgets/image_canvas_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
from collections import OrderedDict
import numpy
from typing import Tuple, List
from tkinter.messagebox import showinfo

from tk_builder.widgets.derived_widgets import CopyableMessageBox

from sarpy.geometry.geometry_elements import LinearRing
from sarpy.geometry.geocoords import geodetic_to_ecf, ecf_to_ned
Expand Down Expand Up @@ -1321,7 +1322,7 @@ def on_left_mouse_click(self, event):
def show_coordinate_details(self):
self.coordinate_string_formatting_function()
if self.coordinate_string is not None:
showinfo('Coordinate Details', message=self.coordinate_string)
CopyableMessageBox('Coordinate Details', message=self.coordinate_string, width=60, height=8)

def coordinate_string_formatting_function(self):
self.coordinate_string = 'Row/Column: ({0:0.1f}, {1:0.1f})'.format(*self.image_coords)
Expand Down Expand Up @@ -1395,24 +1396,11 @@ def on_left_mouse_click(self, event):
return

canvas_event = _get_canvas_event_coords(self.image_canvas, event)
if self.mode == "init":
new_coords = (canvas_event[0], canvas_event[1], canvas_event[0], canvas_event[1])
self.image_canvas.modify_existing_shape_using_canvas_coords(
self.shape_id, new_coords, update_pixel_coords=True)
self.mode = "normal"
self.insert_at_index = 1
else:
if self.insert_at_index > 1:
self.insert_at_index = 1
if self.insert_at_index < 0:
self.insert_at_index = 0
old_coords = self.image_canvas.get_shape_canvas_coords(self.shape_id)
new_coords, _ = _modify_coords(
self.image_canvas, self.shape_id, old_coords,
canvas_event[0], canvas_event[1],
self.insert_at_index, insert=False)
self.image_canvas.modify_existing_shape_using_canvas_coords(
self.shape_id, new_coords, update_pixel_coords=True)
new_coords = (canvas_event[0], canvas_event[1], canvas_event[0], canvas_event[1])
self.image_canvas.modify_existing_shape_using_canvas_coords(
self.shape_id, new_coords, update_pixel_coords=True)
self.mode = "normal"
self.insert_at_index = 1

def on_left_mouse_motion(self, event):
self.mouse_moved = True
Expand Down Expand Up @@ -1474,7 +1462,7 @@ def on_mouse_wheel(self, event):
def show_measurement_details(self, event):
self.image_coords = self.vector_object.image_coords
self.coordinate_string_formatting_function()
showinfo('Measurement Details', message=self.coordinate_string)
CopyableMessageBox('Measurement Details', message=self.coordinate_string, width=90, height=10)

def coordinate_string_formatting_function(self):
crd = self.image_coords
Expand All @@ -1489,7 +1477,7 @@ def coordinate_string_formatting_function(self):
self.coordinate_string += '\n-----------------\n{}: '.format(trans_string)

if trans_string.startswith('LLH'):
self.coordinate_string += '({0:0.8f}, {1:0.8f}, {2:0.2f}) ->\n '.format(*transformed_coords[0, :])
self.coordinate_string += '({0:0.8f}, {1:0.8f}, {2:0.2f}) -> '.format(*transformed_coords[0, :])
self.coordinate_string += '({0:0.8f}, {1:0.8f}, {2:0.2f})\n'.format(*transformed_coords[1, :])
ecf_coords = geodetic_to_ecf(transformed_coords)
bearing_vector_ned = ecf_to_ned(ecf_coords[1, :] - ecf_coords[0, :], ecf_coords[0, :], absolute_coords=False)
Expand Down