Skip to content

Commit

Permalink
docs: add Doxygen documentation
Browse files Browse the repository at this point in the history
* add Doxygen to project
* create Doxyfile
* add documentation to controllers
* add documentation to models
* add documentation to views
  • Loading branch information
Caio-Coldebella committed Feb 11, 2024
1 parent 7144160 commit feb7325
Show file tree
Hide file tree
Showing 50 changed files with 4,185 additions and 48 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ tests/
__pycache__/
*.py[cod]
*$py.class

/html
# C extensions
*.so

Expand Down
2,681 changes: 2,681 additions & 0 deletions Doxyfile

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions micview/controllers/hooks/image_canvas_hooks.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
##
# @brief: This file contains the hooks for the image canvas
#


# Imports
import importlib
from types import ModuleType
from typing import Any
models: ModuleType = importlib.import_module(name='micview.models.getters')
from micview.controllers.services.tools.cursor_tool import updateChannelsIntensity

# Functions
def actionOnChild(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
if(models.states['toolframe_states'].selected_tool == "cursor"):
updateChannelsIntensity()
parent: object = models.views['objects_ref'].ImagesFrame
Expand All @@ -22,6 +34,11 @@ def actionOnChild(* args: Any) -> None:
raise IndexError

def updateAllChilds(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
if(models.states['toolframe_states'].selected_tool == "cursor"):
updateChannelsIntensity()
parent: object = models.views['objects_ref'].ImagesFrame
Expand Down
11 changes: 11 additions & 0 deletions micview/controllers/hooks/loading_states_hooks.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
##
# @brief: This file contains the hook for the loading state.
#

# Imports
import importlib
from types import ModuleType
from typing import Any
models: ModuleType = importlib.import_module(name='micview.models.getters')

# Functions
def loadingHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
from micview.controllers.services.menu.callbacks_onclick import changeButtonsState, handleOnLoading, updateRadiobool
if(models.states['loading_states'].loading):
if(models.states['toolframe_states'].tool_is_set):
Expand Down
16 changes: 16 additions & 0 deletions micview/controllers/hooks/optional_states_hooks.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
##
# @brief: This file contains the hooks for the optional states.
#

# Imports
import importlib
from types import ModuleType
models: ModuleType = importlib.import_module(name='micview.models.getters')

# Functions
def imageIsSquareHook(* args: None) -> None:
"""!
@brief: This function is called when the image is square
@param args: None
@return: None
"""
if(models.states['loading_states'].image_is_loaded and not models.states['loading_states'].loading):
models.states['image_canvas_states'].update_all_childs = True

def maskIsSetHook(* args: None) -> None:
"""!
@brief: This function is called when the mask is set
@param args: None
@return: None
"""
if(models.states['loading_states'].mask_is_loaded and not models.states['loading_states'].loading):
models.states['image_canvas_states'].update_all_childs = True
32 changes: 32 additions & 0 deletions micview/controllers/hooks/toolframe_states_hooks.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,60 @@
##
#
# @brief: This file contains the hooks for the toolframe_states
#

# Imports
import importlib
from types import ModuleType
from typing import Any
models: ModuleType = importlib.import_module(name='micview.models.getters')
from micview.controllers.services.tools.toolframe import setTool

# Functions
def channelSelectHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
if(models.states['loading_states'].image_is_loaded and not models.states['loading_states'].loading):
models.states['image_canvas_states'].update_all_childs = True

def selectedToolHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
tool: str = models.states['toolframe_states'].selected_tool
master: object = models.views['objects_ref'].ToolFrame
setTool(tool=tool, master=master)
models.states['image_canvas_states'].update_all_childs = True

def toolIsSetHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
if(models.states['toolframe_states'].tool_is_set):
models.states['toolframe_states'].selected_tool = "cursor"
else:
del models.views['objects_ref'].ToolFrame
models.states['toolframe_states'].selected_tool = "none"

def transparencyLevelHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
models.states['image_canvas_states'].update_all_childs = True

def zoomHook(* args: Any) -> None:
"""!
@brief: This function is called when the user clicks in one of the childs of the image canvas
@param args: Any
@return: None
"""
models.states['image_canvas_states'].update_all_childs = True
21 changes: 21 additions & 0 deletions micview/controllers/services/files/file_reader.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
##
# @brief: This file contains the file reader service, which is responsible for reading the image and mask files.
#

# Imports
import numpy as np
from typing import Any, List, Dict
import SimpleITK as sitk
from micview.models.getters import data

# Functions
def orientImage(file: sitk.Image) -> List[Any]:
"""!
@brief: This function is used to orient the image
@param file: sitk.Image
@return: List[Any]
"""
Orient = sitk.DICOMOrientImageFilter()
Orient.SetDesiredCoordinateOrientation(DesiredCoordinateOrientation="LPI")
oriented_image: Any = Orient.Execute(image1=file)
Expand All @@ -17,6 +28,11 @@ def orientImage(file: sitk.Image) -> List[Any]:
return extracted

def readImageFile(path: str) -> List[Any]:
"""!
@brief: This function is used to read the image file
@param path: str
@return: List[Any]
"""
MetadatasFile: sitk.Image = sitk.ReadImage(fileName=path)
image_metadatas: Dict[str, Any] = dict()
for key in MetadatasFile.GetMetaDataKeys():
Expand All @@ -26,6 +42,11 @@ def readImageFile(path: str) -> List[Any]:
return ArrayFromImage

def readMaskFile(path: str) -> List[Any]:
"""!
@brief: This function is used to read the mask file
@param path: str
@return: List[Any]
"""
MetadatasFile: sitk.Image = sitk.ReadImage(fileName=path)
mask_metadatas: Dict[str, Any] = dict()
for key in MetadatasFile.GetMetaDataKeys():
Expand Down
69 changes: 65 additions & 4 deletions micview/controllers/services/image_viewer/ImageCanvasController.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
##
# @brief: This class is responsible for handling the canvas widget that displays the image slices.
#

# Imports
from ast import Dict
import numpy as np
from PIL import Image, ImageTk
Expand All @@ -8,8 +13,17 @@
from micview.controllers.services.image_viewer.services import calcCanvasImageSize, get3DCoordinate, getEquivalentPoint, getInverseEquivalentPoint
from micview.controllers.validations.validate_point import getNearestValidPoint

# Class
class ImageCanvasController:
"""!
@brief: This class is responsible for handling the canvas widget that displays the image slices.
"""
def __init__(self, master: tk.Canvas) -> None:
"""!
@brief: Constructor method
@param master: tk.Canvas
@return: None
"""
super().__init__()
self.master: tk.Canvas = master
self.id: int = self.master.id
Expand All @@ -22,21 +36,40 @@ def __init__(self, master: tk.Canvas) -> None:

@property
def canvas_shape(self) -> Tuple[int, int]:
"""!
@brief: Getter method
@return: Tuple[int, int]
"""
return (self.master.winfo_width(), self.master.winfo_height())

def eventHandler(self, type: str) -> None: #when other child suffer click
def eventHandler(self, type: str) -> None:
"""!
@brief: This method is used to handle the events
@param type: str
@return: None
"""
if(type == "action_on_child"):
self.refresh()
elif(type == "update_all_childs"):
self.actual_tool = states['toolframe_states'].selected_tool
self.resize()

def resize(self, e: Any = None) -> None:#Resizes the canvas widget
def resize(self, e: Any = None) -> None:
"""!
@brief: This method is used to resize the canvas widget
@param e: Any
@return: None
"""
image_shape: Tuple[int] = getImageSlices(axis=self.id).shape
self.canvas_image_size: Tuple[int, int] = calcCanvasImageSize(canvas_shape=self.canvas_shape, image_shape=image_shape)
self.refresh()

def click(self, e: Any) -> None:#Handles clicks on canvas
def click(self, e: Any) -> None:
"""!
@brief: This method is used to handle the click event
@param e: Any
@return: None
"""
if(self.actual_tool == "zoom"):
if(int(e.type) == 4):
self.last_clicked_coord = [e.x, e.y]
Expand All @@ -58,7 +91,11 @@ def click(self, e: Any) -> None:#Handles clicks on canvas
self.drawCross()
states['image_canvas_states'].action_on_child = self.id

def refresh(self) -> None:# Refreshs the canvas objects
def refresh(self) -> None:
"""!
@brief: This method is used to refresh the canvas widget
@return: None
"""
self.zoomed_image()
self.drawImage()
self.master.delete('orient_text')
Expand All @@ -77,6 +114,10 @@ def refresh(self) -> None:# Refreshs the canvas objects
self.drawCross()

def zoomed_image(self):
"""!
@brief: This method is used to zoom the image
@return: None
"""
self.original_image = Image.fromarray(obj=getImageSlices(axis=self.id), mode='L')
original_image_size = self.original_image.size
w,h = original_image_size[0]//2, original_image_size[1]//2
Expand All @@ -87,16 +128,32 @@ def zoomed_image(self):
self.image_data = ImageTk.PhotoImage(image=self.zoomed_img.resize(size=self.canvas_image_size, resample=Image.NEAREST))

def zoomed_mask(self):
"""!
@brief: This method is used to zoom the mask
@return: None
"""
self.zoomed_msk = self.mask_image.crop(box=self.zoom_area)
self.mask_data = ImageTk.PhotoImage(image=self.zoomed_msk.resize(size=self.canvas_image_size, resample=Image.NEAREST))

def drawImage(self) -> None:
"""!
@brief: This method is used to draw the image
@return: None
"""
self.drawn_image: int = self.master.create_image((self.master.centerX, self.master.centerY), image=self.image_data, anchor="center", tags=("image",))

def drawMask(self) -> None:
"""!
@brief: This method is used to draw the mask
@return: None
"""
self.drawn_mask: int = self.master.create_image((self.master.centerX, self.master.centerY), image=self.mask_data, anchor="center", tags=("mask",))

def drawOrientText(self) -> None:
"""!
@brief: This method is used to draw the orientation text
@return: None
"""
self.orient_text: Dict[str, Any] = data['files_data'].orient_text[self.id]
if(self.orient_text):
self.drawn_orient_text: int = self.master.create_text((10,self.master.centerY), text=f"{self.orient_text[0]}", font=('Cambria',15,'bold'), fill="#EA2027", anchor="w", tags=("orient_text",))
Expand All @@ -105,6 +162,10 @@ def drawOrientText(self) -> None:
self.drawn_orient_text: int = self.master.create_text((self.master.centerX,self.canvas_shape[1] -3), text=f"{self.orient_text[3]}", fill="#EA2027", font=('Cambria',13,'bold'), anchor="s", tags=("orient_text",))

def drawCross(self) -> None:
"""!
@brief: This method is used to draw the cross
@return: None
"""
x,y = getInverseEquivalentPoint(id=self.id, canvas_shape=self.canvas_shape, canvas_image_size=self.canvas_image_size, zoom_area=self.zoom_area)
imgTop = self.canvas_shape[1]/2 - self.canvas_image_size[1]/2
imgBottom = self.canvas_shape[1]/2 + self.canvas_image_size[1]/2
Expand Down
26 changes: 26 additions & 0 deletions micview/controllers/services/image_viewer/ImageFrameController.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
##
# @brief This file contains the ImageFrameController class, which is responsible for controlling the ImageFrame class.
#

# Imports
from threading import Event, Thread
from micview.models.getters import views
from micview.controllers.services.loading.Animation import Animation
from threading import Event, Thread
from micview.models.getters import views

# Class
class LoadingCircles(Thread):
"""!
@brief This class is responsible for controlling the loading circles.
"""
def __init__(self, event: Event) -> None:
"""!
@brief Constructor method
@param event: Event
@return None
"""
self.event: Event = event
super().__init__(daemon=True)
self.images_frame: object = views['objects_ref'].ImagesFrame
Expand All @@ -14,6 +28,10 @@ def __init__(self, event: Event) -> None:
self.animation_s = self.images_frame.sagital.loading_circle = Animation(master=self.images_frame.sagital, event=self.event)

def run(self) -> None:
"""!
@brief This method is used to start the loading circles
@return None
"""
self.animation_a.start()
self.animation_c.start()
self.animation_s.start()
Expand All @@ -22,6 +40,10 @@ def run(self) -> None:
self.animation_s.join()

def enableAllCanvas() -> None:
"""!
@brief This function is used to enable all canvas
@return None
"""
images_frame: object = views['objects_ref'].ImagesFrame
images_frame.axial.delete("all")
images_frame.axial.bind('<Configure>', images_frame.axial.controller.resize)
Expand All @@ -38,6 +60,10 @@ def enableAllCanvas() -> None:
images_frame.update()

def disableAllCanvas() -> None:
"""!
@brief This function is used to disable all canvas
@return None
"""
images_frame: object = views['objects_ref'].ImagesFrame
images_frame.axial.delete("all")
images_frame.axial.unbind('<Configure>')
Expand Down
Loading

0 comments on commit feb7325

Please sign in to comment.